前言:好久没有写博客,最近一年感觉真是好忙,各种做不完的工作。相信很多上班族都会有这种感觉。最近对NFC进行写卡操作,需要计算一个校验位。一般情况下,校验位多数是由前几个字节进行异或运算所得。
现在我就先说一下我使用的场景:
把一个16字节的数据写到CPU卡(如交通卡)里面,最后一字节是校验码---前十五字节异或。
我开始从网上找了一些别人写的算法发现计算后结果不对,或者就是写的太复杂了,于是自己就写了一个,感觉也比较简单,现在分享给大家,希望一起交流一下。
第一节:什么是异或运算(主要摘自百度百科,熟悉的童靴可以跳过)
定义:
|
00000000
|
xor
|
00000000
|
----------------------------------
|
|
|
00000000
|
|
11111111
|
xor
|
00000000
|
----------------------------
|
|
|
11111111
|
|
0101
|
xor
|
0010
|
----------------------------
|
|
|
0111
|
1
2
3
|
a=a^b; b=b^a; a=a^b; |
1
2
3
|
a1=a^b b=a1^b a=a1^b=a1^(a1^b)=a1^a1^b=b |
1
|
a=a^b^(b=a); //此类形式是不正确的UB行为,在不同编译器中会有不同的结果,切勿使用 |
<span style="font-size:18px;">private static String xor(String strHex_X,String strHex_Y){ //将x、y转成二进制形式 String anotherBinary=Integer.toBinaryString(Integer.valueOf(strHex_X,16)); String thisBinary=Integer.toBinaryString(Integer.valueOf(strHex_Y,16)); String result = ""; //判断是否为8位二进制,否则左补零 if(anotherBinary.length() != 8){ for (int i = anotherBinary.length(); i <8; i++) { anotherBinary = "0"+anotherBinary; } } if(thisBinary.length() != 8){ for (int i = thisBinary.length(); i <8; i++) { thisBinary = "0"+thisBinary; } } //异或运算 for(int i=0;i<anotherBinary.length();i++){ //如果相同位置数相同,则补0,否则补1 if(thisBinary.charAt(i)==anotherBinary.charAt(i)) result+="0"; else{ result+="1"; } } Log.e("code",result); return Integer.toHexString(Integer.parseInt(result, 2)); } </span>
注意:以上方法是针对一个十六进制字符串一字节之间的异或运算,如对十五字节的十六进制字符串异或运算:1312f70f900168d900007df57b4884
先进行拆分:13 12 f7 0f 90 01 68 d9 00 00 7d f5 7b 48 84
13 xor 12-->1
1 xor f7-->f6
f6 xor 0f-->f9
....
62 xor 84-->e6
即,得到的一字节校验码为:e6
原文地址:http://blog.csdn.net/acrambler/article/details/45743157