目录
十六进制文本 与 十六进制数据 转换
十六进制字符串十六进制文本十六进制数据格式化
纯C编写,支持空格与逗号分隔符 ,支持大小写 ,无视0x前缀,无视多个分隔符;
甚至"0xaa,,,,,,, f f0,0f 0xb acddfe 0xGFff\0"也可以识别,代码逻辑可能存在漏洞,还需要各位自己仔细甄别。
代码给出来是给大家参考学习的,代码写的不怎么样,不希望大家简单的去复制,而是希望大家去提高自己。
注意:虽然无视错误字母,但注意识别结果顺序,例如0xGFff,识别为FF、F,转为0xFF,0x0F,而不是F、FF
使用方法
int main(void)
{
uint8_t byte[250];
char str[250];
while(1)
{
StrToHex("0xaa,,,,,,, 0xb acddfe 0xGFff\0",byte);
HexToStr(str,byte);
}
}
结果演示
没有安装什么软件,直接用KEIL写的,软件模拟就可以当C代码编译器了
函数代码
#include <stdio.h>
#include <string.h>
/*代码分为两个部分,第一个部分将字符串填充到字母组内,第二部分计算每个字母组内的值,代码并不是最佳解,但提供解决思路*/
uint8_t StrToHex(char* str, uint8_t *hex)
{
uint16_t num = 0;
uint16_t i;
uint8_t tem_str[255][2];//255个字母组
uint8_t tem_str_i = 0;//字母组总数,作为最后返回的参数
uint8_t tem_str_i_i = 0;//当前字母组内填充字母数,为0时表示填充第一个字母,非0时表示已经填充过一个字母
num = strlen(str);
/*将字符串分割到tem_str数组中,最多两个字母为一组*/
for(i = 0 ; i< num ; i++)
{
if((*(str+i) == ' '||*(str+i) == ','))/*判断字符是否为分割符,可以自己添加各种分隔符*/
{
if(tem_str_i_i>0)/*当字母组内已有填充字母,遇到分割符,结束当前字母组的填充*/
{
tem_str_i_i = 0;
tem_str_i++;
if(tem_str_i>=255)/*当字母组超过定义的255时,退出填充*/
break;
}
}
else if((*(str+i) >= '0' && *(str+i) <= '9')||(*(str+i) >= 'A' && *(str+i) <= 'F')||(*(str+i) >= 'a' && *(str+i) <= 'f'))/*判断字符是否在规定的字母规则里*/
{
if(*(str+i) != '0' )/*如果字符不是0,则直接添加进入字母组*/
{
if(tem_str_i_i == 0)/*填充第一个字母*/
{
tem_str[tem_str_i][0] = *(str+i);
tem_str_i_i++;
}
else/*填充第二个字母,且字母组加一,等待下一个字母填充到下一个字母组内*/
{
tem_str[tem_str_i][1] = *(str+i);
tem_str_i++;
if(tem_str_i>=255)
break;
tem_str_i_i = 0;
}
}
else/*如果字符是0,则判断下一个字母是不是x或X,用来忽略掉0x前缀,这个步骤是必须的*/
{
if(i < num-1)/*判断下一个字母是不是x或X,如果是,则忽略掉这个0,当轮询到下一个字母x时,因为其不在0~9,A~F,a~f范围内,所以当做错误字母忽略掉*/
{
if(*(str+i+1) != 'x'&&*(str+i+1) != 'X')
{
if(tem_str_i_i == 0)/*填充第一个字母*/
{
tem_str[tem_str_i][0] = *(str+i);
tem_str_i_i++;
}
else/*填充第二个字母,且字母组加一,等待下一个字母填充到下一个字母组内*/
{
tem_str[tem_str_i][1] = *(str+i);
tem_str_i++;
if(tem_str_i>=255)
break;
tem_str_i_i = 0;
}
}
}
else/*当这个字母是最后一个字母的时候,不需要判断了,直接添加到字母组中*/
{
if(tem_str_i_i == 0)
{
tem_str[tem_str_i][0] = *(str+i);/*填充第一个字母*/
tem_str_i_i++;
}
else
{
tem_str[tem_str_i][1] = *(str+i);/*填充第二个字母,且字母组加一,等待下一个字母填充到下一个字母组内*/
tem_str_i++;
if(tem_str_i>=255)/*当字母组超过定义的255时,退出填充*/
break;
tem_str_i_i = 0;
}
}
}
}
}
/*计算字母组的值,因为tem_str_i从0开始计算,因此实际数量需要再+1*/
for(i = 0 ; i < tem_str_i+1 ; i++)
{
hex[i] = 0;
if(tem_str[i][1] > 0)/*计算是从后往前,而字母组填充是从前往后填充,需要排除只有一个字符的情况,具体为啥要区别只有一个字符的情况,可以打断点单步调试,本人写完代码自己也忘了,好像是当只有一个字母时,会填充到前面,把他当成0xF0,而不是0x0F,所以为了把他算成0x0F,所以区分出来,大家自己看看吧*/
{
if(tem_str[i][1] >= '0' && tem_str[i][1] <= '9')
*(hex+i) = tem_str[i][1] - '0';
else if(tem_str[i][1] >= 'A' && tem_str[i][1] <= 'F')
*(hex+i) = tem_str[i][1] - 'A'+10;
else if(tem_str[i][1] >= 'a' && tem_str[i][1] <= 'f')
*(hex+i) = tem_str[i][1] - 'a'+10;
if(tem_str[i][0] >= '0' && tem_str[i][0] <= '9')
*(hex+i) += (tem_str[i][0] - '0')*16;
else if(tem_str[i][0] >= 'A' && tem_str[i][0] <= 'F')
*(hex+i) += (tem_str[i][0] - 'A'+10)*16;
else if(tem_str[i][0] >= 'a' && tem_str[i][0] <= 'f')
*(hex+i) += (tem_str[i][0] - 'a'+10)*16;
}
else
{
if(tem_str[i][0] >= '0' && tem_str[i][0] <= '9')
*(hex+i) += (tem_str[i][0] - '0');
else if(tem_str[i][0] >= 'A' && tem_str[i][0] <= 'F')
*(hex+i) += (tem_str[i][0] - 'A'+10);
else if(tem_str[i][0] >= 'a' && tem_str[i][0] <= 'f')
*(hex+i) += (tem_str[i][0] - 'a'+10);
}
}
return tem_str_i;
}
/*数据转成16进制文本就简单多了,用sprintf的格式化方法就可以了,前人栽树后人乘凉嘛,这里面区分一下数据小于16时,会输出0xF,而我们需要的是0x0F其他没什么需要注意的*/
void HexToStr(char *str ,uint8_t *hex)
{
uint8_t num,i;
num = strlen((char *)hex);
sprintf(str,"0x%X",(uint8_t)*(hex));
for(i = 1 ; i < num ; i++)
{
if(*(hex+i) < 16)
sprintf(str,"%s,0x0%X",str,(uint8_t)*(hex+i));
else
sprintf(str,"%s,0x%X",str,(uint8_t)*(hex+i));
}
}