课上测试:商用密码标准实现

发布于:2024-12-22 ⋅ 阅读:(17) ⋅ 点赞:(0)

完成下面任务(29分)

1 在 Ubuntu 或 openEuler 中完成任务(推荐openEuler)

2 简述 GM/T0009 4种数据转换的功能,根据你的理解,每种转换功能给出至少一个例子 (8分)

将位串转换位字节串
将字节串转换为位串
将字节串转换为整数
将整数转换为字节串

将位串转换为字节串


#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// 位串转8位字节串函数
void bitstring_to_bytes(char *bitstring, int blen, char *bytes) {
int mlen = (blen + 7) / 8;
for (int i = 0; i < mlen; i++) {
bytes[i] = 0;
for (int j = 0; j < 8; j++) {
int index = blen - 8 * (mlen - 1 - i) - j - 1;
if (index >= 0 && bitstring[index] == '1') {
bytes[i] |= 1 << j;
}
}
}
}

int main() {
char bitstring[1000];
char bytes[1000];
int blen;

printf("请输入位串长度:");
scanf("%d", &blen);

printf("请输入位串:");
scanf("%s", bitstring);

bitstring_to_bytes(bitstring, blen, bytes);

int mlen = (blen + 7) / 8;
printf("转换后的字节串:");
for (int i = 0; i < mlen; i++) {
printf("%02X ", (unsigned char)bytes[i]);
}
printf("\n");

return 0;
}

将字节串转换为位串

#include <stdio.h>
#include <stdlib.h>

// 函数:将字节转换为二进制字符串
void byte_to_binary(char byte, char* binary_str) {
    for (int i = 7; i >= 0; --i) {
        binary_str[7 - i] = ((byte & (1 << i))? '1' : '0');
    }
    binary_str[8] = '\0';
}

// 函数:将8位字节串转换为位串
void bytes_to_bitstring(char* bytes, int mlen, char* bitstring) {
    int index = 0;
    for (int i = 0; i < mlen; ++i) {
        char binary[9];
        byte_to_binary(bytes[i], binary);
        for (int j = 0; j < 8; ++j) {
            bitstring[index++] = binary[j];
        }
    }
    bitstring[index] = '\0';
}

int main() {
    // 示例字节串
    char bytes[] = {0x12, 0x34, 0x56};
    int mlen = sizeof(bytes) / sizeof(bytes[0]);
    char* bitstring = (char*)malloc(mlen * 8 + 1);

    bytes_to_bitstring(bytes, mlen, bitstring);

    printf("位串: %s\n", bitstring);

    free(bitstring);
    return 0;
}

将字节串转换为整数

#include <stdio.h>
#include <stdlib.h>

// 函数:将8位字节串转换为整数
unsigned int bytes_to_int(unsigned char* M, int mlen) {
    unsigned int x = 0;
    for (int i = 0; i < mlen; i++) {
        x += (1 << (8 * (mlen - 1 - i))) * M[i];
    }
    return x;
}

int main() {
    // 示例字节串
    unsigned char M[] = {0x12, 0x34};
    int mlen = sizeof(M) / sizeof(M[0]);

    unsigned int x = bytes_to_int(M, mlen);
    printf("转换后的整数: %u\n", x);

    return 0;
}

将整数转换为字节串

#include <stdio.h>
#include <stdlib.h>

// 函数:将整数转换为8位字节串
void int_to_bytes(int x, int mlen, unsigned char *M) {
    for (int i = 0; i < mlen; i++) {
        M[i] = (x >> (8 * (mlen - 1 - i))) & 0xFF;
    }
}

int main() {
    int x;
    int mlen;

    // 输入非负整数x和期望的8位字节串长度mlen
    printf("请输入非负整数x:");
    scanf("%d", &x);
    printf("请输入期望的8位字节串长度mlen:");
    scanf("%d", &mlen);

    // 检查基本限制
    if (x >= (1 << (8 * mlen))) {
        printf("超出范围,无法转换。\n");
        return 1;
    }

    // 分配内存用于存储8位字节串
    unsigned char *M = (unsigned char *)malloc(mlen);
    if (M == NULL) {
        printf("内存分配失败。\n");
        return 1;
    }

    // 转换整数为8位字节串
    int_to_bytes(x, mlen, M);

    // 输出8位字节串
    printf("转换后的8位字节串:");
    for (int i = 0; i < mlen; i++) {
        printf("%02X ", M[i]);
    }
    printf("\n");

    // 释放内存
    free(M);

    return 0;
}

3 参考课程代码sdfproject,基于一个模块utils.c,utils.h使用四个函数分别实现4种数据转换的功能(12分)

utils.c

#include <stdio.h>
#include <string.h>
#include "utils.h"
 
// 将位串转换为8位字节串
void bitStringToByteString(const uint8_t *bitString, size_t bitLength, uint8_t *byteString) {
    size_t byteLength = (bitLength + 7) / 8;
    memset(byteString, 0, byteLength);
    for (size_t i = 0; i < bitLength; ++i) {
        if (bitString[i / 8] & (1 << (7 - (i % 8)))) {
            byteString[i / 8] |= 1 << (7 - (i % 8));
        }
    }
}
 
// 将8位字节串转换为位串
void byteStringToBitString(const uint8_t *byteString, size_t byteLength, uint8_t *bitString) {
    size_t bitLength = byteLength * 8;
    memset(bitString, 0, bitLength);
    for (size_t i = 0; i < bitLength; ++i) {
        if (byteString[i / 8] & (1 << (7 - (i % 8)))) {
            bitString[i / 8] |= 1 << (7 - (i % 8));
        }
    }
}
 
// 将8位字节串转换为整数
uint64_t byteStringToInt(const uint8_t *byteString, size_t byteLength) {
    uint64_t result = 0;
    for (size_t i = 0; i < byteLength; ++i) {
        result = (result << 8) | byteString[i];
    }
    return result;
}
 
// 将整数转换为8位字节串
void intToByteString(uint64_t value, size_t byteLength, uint8_t *byteString) {
    for (size_t i = 0; i < byteLength; ++i) {
        byteString[byteLength - 1 - i] = (value >> (i * 8)) & 0xFF;
    }
}

utils.h

#ifndef UTIL_H
#define UTIL_H
 
#include <stdint.h>
#include <stddef.h>
 
// 将位串转换为8位字节串
void bitStringToByteString(const uint8_t *bitString, size_t bitLength, uint8_t *byteString);
 
// 将8位字节串转换为位串 
void byteStringToBitString(const uint8_t *byteString, size_t byteLength, uint8_t *bitString);
 
// 将8位字节串转换为整数
uint64_t byteStringToInt(const uint8_t *byteString, size_t byteLength);
 
// 将整数转换为8位字节串 
void intToByteString(uint64_t value, size_t byteLength, uint8_t *byteString);
 
#endif // UTIL_H 
root@LAPTOP-PRC71A0C:~/bestidiocs2024/ch06/gmt0009/src# vim utils.h
root@LAPTOP-PRC71A0C:~/bestidiocs2024/ch06/gmt0009/src# vim utils.c
root@LAPTOP-PRC71A0C:~/bestidiocs2024/ch06/gmt0009/src# ls
utils.c  utils.h

4 src中在testsdf.c中编写main函数 测试四个转换功能。 (6分)

root@LAPTOP-PRC71A0C:~/bestidiocs2024/ch06/gmt0009/src# vim testsdf.c

testsdf.c

#include <stdio.h>
#include <string.h>
#include "utils.h"
 
// 打印字节数组
void printByteArray(const uint8_t *array, size_t length) {
    for (size_t i = 0; i < length; ++i) {
        printf("%02x ", array[i]);
    }
    printf("\n");
}
 
// 打印位数组
void printBitArray(const uint8_t *array, size_t length) {
    for (size_t i = 0; i < length; ++i) {
        for (size_t j = 0; j < 8; ++j) {
            printf("%d", (array[i] >> (7 - j)) & 1);
        }
        printf(" ");
    }
    printf("\n");
}
 
int main() {
    // 测试位串转换为字节串
    uint8_t bitString[] = {0xAA, 0x55, 0x0F, 0xF0};
    uint8_t byteString[4];
    bitStringToByteString(bitString, 32, byteString);
    printf("Bit string to byte string: ");
    printByteArray(byteString, 4);
 
    // 测试字节串转换为位串 
    uint8_t bitStringOut[32];
    byteStringToBitString(byteString, 4, bitStringOut);
    printf("Byte string to bit string: ");
    printBitArray(bitStringOut, 4);
 
    // 测试字节串转换为整数 
    uint64_t intValue = byteStringToInt(byteString, 4);
    printf("Byte string to int: %llu\n", intValue);
 
    // 测试整数转换为字节串
    uint64_t testValue = 0x1234567890ABCDEF;
    uint8_t byteStringOut[8];
    intToByteString(testValue, 8, byteStringOut);
    printf("Int to byte string: ");
    printByteArray(byteStringOut, 8);
 
    return 0;
}
root@LAPTOP-PRC71A0C:~/bestidiocs2024/ch06/gmt0009/src# gcc -o testsdf testsdf.c utils.c
testsdf.c: In function ‘main’:
testsdf.c:40:36: warning: format ‘%llu’ expects argument of type ‘long long unsigned int’, but argument 2 has type ‘uint64_t’ {aka ‘long unsigned int’} [-Wformat=]
   40 |     printf("Byte string to int: %llu\n", intValue);
      |                                 ~~~^     ~~~~~~~~
      |                                    |     |
      |                                    |     uint64_t {aka long unsigned int}
      |                                    long long unsigned int
      |                                 %lu
root@LAPTOP-PRC71A0C:~/bestidiocs2024/ch06/gmt0009/src# ls
testsdf  testsdf.c  utils.c  utils.h
root@LAPTOP-PRC71A0C:~/bestidiocs2024/ch06/gmt0009/src# ./testsdf
Bit string to byte string: aa 55 0f f0
Byte string to bit string: 10101010 01010101 00001111 11110000
Byte string to int: 2857701360
Int to byte string: 12 34 56 78 90 ab cd ef
root@LAPTOP-PRC71A0C:~/bestidiocs2024/ch06/gmt0009/src# git add ..
root@LAPTOP-PRC71A0C:~/bestidiocs2024/ch06/gmt0009/src# git commit -m "商用密码标准实现"
[master 7558786] 商用密码标准实现
 4 files changed, 110 insertions(+)
 create mode 100755 ch06/gmt0009/src/testsdf
 create mode 100644 ch06/gmt0009/src/testsdf.c
 create mode 100644 ch06/gmt0009/src/utils.c
 create mode 100644 ch06/gmt0009/src/utils.h

5 提交git log结果(3分)

root@LAPTOP-PRC71A0C:~/bestidiocs2024/ch06/gmt0009/src# git log
commit 7558786284d4c147a518befec991cbd8b511d662 (HEAD -> master)
Author: 魏正一 <11565599+wei-zhengyi@user.noreply.gitee.com>
Date:   Tue Dec 17 11:42:10 2024 +0800

    商用密码标准实现

提交要求 (1’)

记录实践过程和 AI 问答过程,尽量不要截图,给出文本内容
(选做)推荐所有作业托管到 gitee或 github 上
(必做)提交作业 markdown文档,命名为“学号-姓名-作业题目.md”
(必做)提交作业 markdown文档转成的 PDF 文件,命名为“学号-姓名-作业题目.pdf”