前言:好久没有写博客,最近一年感觉真是好忙,各种做不完的工作。相信很多上班族都会有这种感觉。最近对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行为,在不同编译器中会有不同的结果,切勿使用
|
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
注意:以上方法是针对一个十六进制字符串一字节之间的异或运算,如对十五字节的十六进制字符串异或运算: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
补充,给一些朋友增加了一个简单的调用方法,仅供参考:
public String checkcode_0007(String para){
String[] dateArr = new String[15];
try {
dateArr[0] = para.substring(0, 2);
dateArr[1] = para.substring(2, 4);
dateArr[2] = para.substring(4, 6);
dateArr[3] = para.substring(6, 8);
dateArr[4] = para.substring(8, 10);
dateArr[5] = para.substring(10, 12);
dateArr[6] = para.substring(12, 14);
dateArr[7] = para.substring(14, 16);
dateArr[8] = para.substring(16, 18);
dateArr[9] = para.substring(18, 20);
dateArr[10] = para.substring(20, 22);
dateArr[11] = para.substring(22, 24);
dateArr[12] = para.substring(24, 26);
dateArr[13] = para.substring(26, 28);
dateArr[14] = para.substring(28, 30);
} catch (Exception e) {
// TODO: handle exception
}
String code = "";
for (int i = 0; i < dateArr.length-1; i++) {
if(i == 0){
code = xorString(dateArr[i], dateArr[i+1]);
}else{
code = xorString(code, dateArr[i]);
}
}
return code;
}
然后再主函数或者其他方法里面调用:
String code = checkcode_0007("1312f70f900168d900007df57b4884");
code就是获取的校验码了。