1.前言
今日有个朋友跟我讲,要接一个物联网的通信智能锁,远程控制锁的开关。东西已经买好了,但是想要远程通信,必须要用指定的协议发送给机器才可以实现智能开锁。平台准备用阿里云物联网平台,查看文档之后发现需要发送的数据是16进制的hex,并且最后一位的数据必须用BBC异或校验得到的数据才行。网上查询了一下php生成BBC异或校验码的相关资料,发现没有实现的,就手动写了一个。记录一下,以备后用。
2.BBC校验
BCC(Block Check Character/信息组校验码),因校验码是将所有数据异或得出,故俗称异或校验。具体算法是:将每一个字节的数据(一般是两个16进制的字符)进行异或后即得到校验码。
例如16进制数据:01 A0 7C FF 02
计算:01 xor A0 xor 7C xor FF xor 02 = 20
校验码是:20
3.思路
看过BBC的资料后发现,就是要把十六进制的字符按照顺序两哥异或之后拿得到的结果再和下一个异或,看起来非常的简单直接用|两两异或就可以得出结果。但是实践发现,多个的时候会出错,不知道php的内部处理逻辑是怎么样,后来就自己手动用二进制来进行XOR运算,然后得出校验值。
4.代码实现
//hex数据BBC异或校验(两两比较)
function hexXor($hex1, $hex2){
$bin1 = base_convert($hex1, 16, 2);
$bin2 = base_convert($hex2, 16, 2);
$len1 = strlen($bin1);
$len2 = strlen($bin2);
$result = '';
//如果不相等判断补齐再异或
if($len1 != $len2){
if($len1 > $len2){
$temp = '';
for ($i=0; $i < $len1 - $len2; $i++) {
$temp.='0';
}
}else{
$temp = '';
for ($i=0; $i < $len2 - $len1; $i++) {
$temp.='0';
}
}
$bin2 = $temp.$bin2;//不足补0
}
for ($i=0; $i < $len1; $i++) {
$result .= $bin1[$i] == $bin2[$i] ? '0' : '1';
}
return base_convert($result, 2, 16);
}
这是两两比较,获取BBC校验值的函数。
//hex数据BBC异或校验(多个hex数据进行校验)
function hexXorArr($data){
$result = $data[0];
for ($i=0; $i < count($data)-1; $i++) {
$result = hexXor($result, $data[$i+1]);
}
return $result;
}
这是多个数据进行计算的函数,是基于上面基础函数的扩展
5.代码使用
$string1 = '8a';
$string2 = '01';
$string3 = '12';
$string4 = '11';
echo hexXor(hexXor(hexXor($string1, $string2), $string3), $string4);
echo '<hr/>';
echo hexXorArr([$string1, $string2, $string3, $string4]);
运算结果