文章目录
完成下面任务(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”