gpt4 book ai didi

基于 8 个十六进制字节创建一个 unsigned int

转载 作者:行者123 更新时间:2023-11-30 15:54:49 25 4
gpt4 key购买 nike

我正在尝试将 unsigned int 打印为十六进制,但不仅仅是使用 %08X。我需要打印每个字节的 MSB 和 LSB 的十六进制,首先是 MSB。我已经明白了:

unsigned int num = 1234567890;
char *p = (char*)#
for (int i = 0; i < 4; i++) {
printf("%X%X", (*(p+i) & 0xF0) >> 4, *(p+i) & 0x0F);
}
// prints: D2029649

但是,我无法从包含 D2029649 的字符串返回 unsigned int:

short dehex(char hexLetter) {
if(hexLetter > 47 && hexLetter < 58) hexLetter -= 48;
if(hexLetter > 64) hexLetter -= 55;
return hexLetter;
}

unsigned int o = 0;
char *in = "D2029649";
int len = strlen(in);
for(int i = 0; i < len; i++) {
if(i % 2 == 0) {
o |= ((unsigned char)dehex(in[i]) << 4) + dehex(in[i+1]);
o <<= 8;
}
}

不用说,这根本行不通。这两行操作 o 的代码是我尝试撤销原始编码的结果,也是我对如何将字节转回 int 所做的一些研究的结果。

也许我的麻烦来自于对生成十六进制时我实际在做什么的完全误解。

有人有任何提示可以让我朝正确的方向前进,将十六进制恢复为原始的无符号整数吗?

最佳答案

您的练习的目的似乎是根据内存布局将整数转换为字符串,然后再将其转换回来。

否则,您就不会费力地尝试弄清楚您是否位于字节边界上,然后进行位移“体操”。相反,您只需将值左移四位并添加下一个数字,例如:

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

short dehex (char hexLetter) {
if ((hexLetter >= '0') && (hexLetter <= '9'))
return hexLetter - '0';
return hexLetter - 'A' + 10;
}

int main (void) {
unsigned int o = 0;
char *in = "D2029649";
int len = strlen (in);
for (int i = 0; i < len; i++)
o = (o << 4) + dehex (in[i]);
printf ("%X\n", o);
return 0;
}

你会注意到我稍微改变了 dehex 函数,因为我不太喜欢魔法数字,其中字符常量更具可读性(它仍然不能移植到所有实现,例如例如 EBCDIC,但现在这样的东西已经很少了)。

该程序将从该字符串中以大写十六进制输出无符号整数值进行检查:D2029649

但是,十进制值 1234567890 的十六进制为 499602D2,其字节顺序与字符串中的顺序相反。那是因为您采用的是所谓的小端架构。

所以你有两个问题。

首先是您以错误的顺序处理字节以获取原始数字。

您需要从字符串的末尾开始向后工作,例如:

for (int i = len - 2; i >= 0; i -= 2) ...

第二个是您以错误的顺序执行添加/移位操作。

因为您的原始代码在添加后发生了移位,因此它到达D2029649,然后将其左移八位,结果为02964900 - D2 从左侧移入遗忘状态,并在右侧移入零字节。您需要移动然后添加:

o <<= 8;
o |= ((unsigned char)dehex(in[i]) << 4) + dehex(in[i+1]);

最后,虽然不是必需的,但如果您仅使用 unsigned char 返回转换后的 nybble,则可以大大简化代码。我将编写的代码如下所示:

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

unsigned char dehex (char hexLetter) {
if ((hexLetter >= '0') && (hexLetter <= '9'))
return hexLetter - '0';
return hexLetter - 'A' + 10;
}

int main (void) {
unsigned int num = 1234567890;
char *p = (char*) &num;
for (int i = 0; i < 4; i++)
printf("%X%X", (*(p+i) & 0xF0) >> 4, *(p+i) & 0x0F);
putchar ('\n');

unsigned int o = 0;
char *in = "D2029649";
int len = strlen (in);
for (int i = len - 2; i >= 0; i -= 2) {
o <<= 8;
o |= (dehex (in[i]) << 4) + dehex (in[i+1]);
}
printf ("%X, or %u\n", o, o);
return 0;
}

请注意,一次处理一个字节而不是一次处理一个半字节更有意义。使用基于 nybble 的代码,您必须按照 6, 7, 4, 5, 2, 3, 0, 1 的顺序进行数组索引,而不是一个漂亮的小 0..7 循环。

该程序的输出是:

D2029649
499602D2, or 1234567890

表明您正在取回原始号码。

关于基于 8 个十六进制字节创建一个 unsigned int,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12719107/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com