将字节流转换成十六进制字符串

今天的在阅读项目代码的时候遇到的问题。

在研究之后,终于确定每次看到这样的转换问题都会搞不懂,每次都需要花时间绕来绕去的原因。

我在之前没能弄清转换的过程中,字符的计算机存储方式和字符的输出方式的区别,总是出现很多想当然的想法,所以总是在想问题的过程中没头没脑的。

先说转换的要求:

将字节流转换成十六进制字符串。字节流,就是一个一个的字符组成的流,每个字符占一个字节。十六进制字符串,也是由一个个字符组成的。

举例将字节流“AB”转换成十六进制字符串,最后得到的结果应该是“4142”

这是因为字符‘A’就是十六进制的41即0x41,字符‘B’就是十六进制的42,即0x42。

下面来看一些知识。

一个字节在内存中的表现形式:

从0000 0000
到1111 1111


按十进制输出:

从0
到255


按16进制输出:

从0x00

到0xFF


如果‘A'以二进制输出则得到0100 0001

    以十进制输出则得到65

    以十六进制输出得到41

如果‘B'以二进制输出则得到0100 0010

    以十进制输出则得到66

    以十六进制输出得到42


下面我们谈谈怎样将上面已知的转化为一个“4142”这样的字符串

我们可以利用二进制和十六进制的转换关系进行运算:

我们将一个字符的二进制表示划分为两部分,其中前面半部分就是十六进制数的第二位,后半部分就是十六进制数的第一位。

<span style="white-space:pre">	</span>unsigned char c = 'A';
	unsigned char pre = c >> 4;
	unsigned char suf = c & 0x0F;
我们通过位移运算就可以得到‘A’的二进制表示的前半部分,通过与运算就可以得到‘A’的二进制表示的后半部分。

我们得到这些之后并不意味着转换的结束,因为我们得到的紧紧是十六进制表示为4的字符,和十六进制表示为1的字符,字符本身并不是我们想要的数值。如果我们将这些字符按照ascii字符输出,他们并不是我们想要的结果,我们想要的结果是他们的字符表示是0~9和A~F。

下面我们就还需要进行转换:

在上面的代码中字符变量变量pre的十六进制表示是0x04,而实际的字符‘4’的十六进制表示是0x34,他们之间相差0x30.(在asc中所有的十六进制数与它所对应的ascii字符都相差0x30,所以只需要在原来的字符变量上加上0x30即可,0~9是这样)

下面再看看例外:如果pre的十六进制表示是0x0A,此时是怎样的呢?在ascii吗表中,字符‘a’的十六进制表示是0x41,则需要在原来的字符变量上加上0x37.(A~E)

需要注意的内容大概就在上面这些了,下面看完整代码(如有需要自行改动):

#include <iostream>
#include <stdio.h>
#include <string>
using namespace std;
int main()
{
	unsigned char c = 'A';
	cout << "转换前" << endl;
	unsigned char pre = c >> 4;
	printf("以十六进制输出:0x%02x\n",pre);
	printf("以ascii输出:%c\n",pre);
	unsigned char suf = c & 0x0F;
	printf("以十六进制输出:0x%02x\n",suf);
	printf("以ascii输出:%c\n",suf);
	
	pre += 0x30;
	if(pre >0x39)
	{
		pre += 0x07;
	}
	suf += 0x30;
	if(suf >0x39)
	{
		suf += 0x07;
	}
	
	cout << "转换后" << endl;
	printf("以十六进制输出:0x%02x\n",pre);
	printf("以ascii输出:%c\n",pre);
	printf("以十六进制输出:0x%02x\n",suf);
	printf("以ascii输出:%c\n",suf);
	
	
	string s;
	s += pre;
	s += suf;
	cout << "转化后的十六进制字符串" << s;
	return 0;
}




  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值