最近在工作中遇到如下问题:
需要将文件经过SHA256处理后的hash
值与token
的hash
值作异或处理,简单归纳下就是将两个十六进制字符串作异或处理。
分析
-
一个十六进制字符其实表示的是一个字节的低4位,但是在
ASCII
码表中,它是作为一个字符,即占用了一个字节,所以需要先把这个字符转换成对应的十进制数(范围是0~15),同理在异或完成后,需要将这个十进制数(0~15)转换成对应的占据1字节的字符串中的字符。 -
由于我的需求中两个hash值求出来都是64位,但是为了应对更一般的情况,即通常是两个不等长字符串。所以需要将等长的部分异或,再将较长的字符串中未异或部分拷贝到异或过的字符串后面。
-
由于字符串存在小谢字母,所以在异或之前,先将所有字符串转换成大写。
/**
* C/C++两个十六进制字符串异或
* @Filename: hexstrxor.c
*/
#include <stdio.h>
#include <string.h>
#include <math.h>
//ASCII码中将字符转换成对应的十进制数
int char2int( char input )
{
return input>64?(input-55):(input-48);
}
//ASCII码中将十进制数转换成对应的字符
int int2char( char input )
{
return input>9?(input+55):(input+48);
}
//将十六进制字符串HexStr1和HexStr2异或得到HexStr
void hexstrxor( char * HexStr1, char * HexStr2, char * HexStr )
{
int i, iHexStr1Len, iHexStr2Len, iHexStrLenLow, iHexStrLenGap;
//转换成大写并求长度, strupr是非标准的C函数,在Linux下不支持,所以需要自己实现或者使用glib中的g_string_ascii_up ()
strupr( HexStr1 );
strupr( HexStr2 );
iHexStr1Len = strlen( HexStr1 );
iHexStr2Len = strlen( HexStr2 );
//获取最小的长度
iHexStrLenLow = iHexStr1Len<iHexStr2Len?iHexStr1Len:iHexStr2Len;
//获取长度差值
iHexStrLenGap = abs( iHexStr1Len-iHexStr2Len );
//两个十六进制的字符串进行异或
for( i=0; i<iHexStrLenLow; i++ )
{
*(HexStr+i) = char2int( HexStr1[i] ) ^ char2int( HexStr2[i] );
*(HexStr+i) = int2char( *(HexStr+i) );
}
if( iHexStr1Len>iHexStr2Len )
memcpy( HexStr+i, HexStr1+i, iHexStrLenGap );
else if( iHexStr1Len<iHexStr2Len )
memcpy( HexStr+i, HexStr2+i, iHexStrLenGap );
*( HexStr+iHexStrLenLow+iHexStrLenGap ) = 0x00;
}
int main( int argc, char * argv[] )
{
//两个十六进制的字符串以及异或的结果result
char HexStr1[] = "F1A37CD826BE0A38";
char HexStr2[] = "4FBC926A2EED4F0A";
char result[17] = {0};
//调用异或方法
hexstrxor( HexStr1, HexStr2, result );
//打印异或结果
printf( "\nresult=[%s]\n", result );
return 0;
}```
感兴趣可以访问我的个人博客查看更多技术干货:[十六进制字符串异或](http://shuqing.me/2016/07/05/%E5%8D%81%E5%85%AD%E8%BF%9B%E5%88%B6%E5%AD%97%E7%AC%A6%E4%B8%B2%E5%BC%82%E6%88%96/)
网友评论