字符串转ASSII字符编解码
最近在做tetra网络相关的项目时,涉及到字符串转ASSII的方式进行消息的编码方式,以及对应的解码,就整理一下:
1:其实就是把字符串中每个字符,取高四位,存储对应的十六进制值对应的字符串。
2:反向解析,把ASSII字符串每两个做拼接,转成十进制求出assii对应的字符进行存储。
涉及到一个没有关注到的知识点:位运算符:左移(<<)和右移(>>)
注意:左移和右移并不会改变指针指向,配合&,|,^可以对数据做一些列操作
>> 右移符号,对应的二进制位,正数左边补0,负数左边补1
<< 左移符号,对应的二进制位,右边补0,
字符处理:
取字符c高四位对应的数值: (c>>4) & 0xF (先右移4位,即左边二进制补齐4位,求得高四位对应数值)
取字符c低四位对应的数值: c & 0x0F
源码demo:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//最近在做tetra网络相关的项目时,涉及到字符串转ASSII的方式进行消息的编码方式,以及对应的解码,就整理一下
int str2ASSIIHex(const char* str, const int data_len, char* out_buff);
int ASSII2StrHex(const char* assii_str, const int assii_len, char * data, int len);
int main()
{
const char* str= "ABCJKL";
char * assi_str = (char*)malloc((strlen(str)*2));
if(assi_str == NULL)
{
printf("malloc error \n");
return -1;
}
printf("src str:%s \n", str);
str2ASSIIHex(str, strlen(str), assi_str);
printf("ASSII_STR:%s %lu\n", assi_str,strlen(assi_str));
char * dst_str = (char*)malloc(strlen(str));
if(dst_str == NULL)
{
printf("malloc dst str error \n");
free(assi_str);
return -1;
}
ASSII2StrHex(assi_str, strlen(assi_str), dst_str, strlen(str));
printf("dst str:%s %lu \n", dst_str, strlen(dst_str));
free(assi_str);
free(dst_str);
return 0;
}
//把字符串转为assii对应的十六进制内容进行存储 ==》取高四位 存对应的字符 取低四位 存对应的字符
//实际上字符串的长度扩大了2倍
int str2ASSIIHex(const char* str, const int data_len, char* out_buff)
{
if(str == NULL || data_len <= 0 || out_buff == NULL)
{
return -1;
}
char hexval[16] = { '0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
//对字符串数据进行处理 取高四位,低四位然后拼接
for(int j =0; j<data_len; j++)
{
out_buff[j*2] = hexval[(str[j]>>4) & 0xF]; //取高四位
out_buff[j*2+1] = hexval[(str[j]) & 0x0F]; //取低四位
}
//out_buff就是最终转出来的十六进制的数
return 0;
}
//直接把字符转成数字 然后求十六进制
static int char2num(char c)
{
int ret = -1;
switch(c)
{
case '0': ret = 0; break;
case '1': ret = 1; break;
case '2': ret = 2; break;
case '3': ret = 3; break;
case '4': ret = 4; break;
case '5': ret = 5; break;
case '6': ret = 6; break;
case '7': ret = 7; break;
case '8': ret = 8; break;
case '9': ret = 9; break;
case 'a':
case 'A': ret = 10; break;
case 'b':
case 'B': ret = 11; break;
case 'c':
case 'C': ret = 12; break;
case 'd':
case 'D': ret = 13; break;
case 'e':
case 'E': ret = 14; break;
case 'f':
case 'F': ret = 15; break;
}
return ret;
}
//把上文存储的 ASSII转为字符串
int ASSII2StrHex(const char* assii_str, const int assii_len, char * data, int len)
{
if(assii_str == NULL || data == NULL || assii_len/2 >len)
{
printf("paras is null.");
return -1;
}
int assi_num;
for(int i = 0; i<assii_len/2; i++)
{
assi_num = char2num(assii_str[2*i])*16 + char2num(assii_str[2*i+1]);
data[i] = assi_num;
}
return 0;
}
/****************************
//运行结果 注意 这里其实对应的是assii字符对应的十六进制的值字符
src str:ABCJKL
ASSII_STR:4142434a4b4c 12
dst str:ABCJKL 6
*****************************/