前言:好久没有写博客,最近一年感觉真是好忙,各种做不完的工作。相信很多上班族都会有这种感觉。最近对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^bb=a1^ba=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