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]);
運算結果