2014-11-07 5 views
1

я нужна функция, которая генерирует Maxim/Dallas 1Wire CRC 8bit-код, как эту страницу: http://www.datastat.com/sysadminjournal/maximcrc.cgiCRC Maxim/Dallas 1Wire Generation: перевести Visual Basic на PHP

Для этой проблемы я нашел немного Excel Калькулятор для решения. Он работает правильно, но я получил проблему, чтобы перевести ее на язык PHP.

Оригинал VB код:

Private Sub ROMCRC_Click() 

    Dim InHex, OutBinStr As String 
    Dim OutBinArr(1 To 56) As Integer 
    Dim OutDec, i, CRC(1 To 8), CRCTemp As Integer 

    InHex = Range("ROMByte1").Value & Range("ROMByte2").Value & Range("ROMByte3").Value & Range("ROMByte4").Value & Range("ROMByte5").Value & Range("ROMByte6").Value & Range("ROMByte7").Value 
    OutBinStr = HexToBin(InHex) 

    ' Convert string to array, LSB = OutBinArr(1) 
    For i = 1 To 56 
    OutBinArr(57 - i) = Mid$(OutBinStr, i, 1) ' Split(OutBinStr) 
    Next i 

    'Initialize CRC 
    For i = 1 To 8 
     CRC(i) = 0 
    Next i 

    'Calculate CRC 
    For i = 1 To 56 
     CRCTemp = CRC(1) Xor OutBinArr(i) 
     CRC(1) = CRC(2) 
     CRC(2) = CRC(3) 
     CRC(3) = CRC(4) Xor CRCTemp 
     CRC(4) = CRC(5) Xor CRCTemp 
     CRC(5) = CRC(6) 
     CRC(6) = CRC(7) 
     CRC(7) = CRC(8) 
     CRC(8) = CRCTemp 
    Next i 

    DecCRC = BinToDec(CRC) 

    Range("ROMCRCValue").Value = DecCRC 

End Sub 


Private Function HexToBin(hstr) 
'convert hex string to binary string 
    cnvarr = Array("0000", "0001", "0010", "0011", _ 
      "0100", "0101", "0110", "0111", "1000", _ 
      "1001", "1010", "1011", "1100", "1101", _ 
      "1110", "1111") 
    bstr = "" 
    For i = 1 To Len(hstr) 
     hdgt = Mid(hstr, i, 1) 
     cix = CInt("&H" & hdgt) 
     bstr = bstr & cnvarr(cix) 
    Next 
    HexToBin = bstr 
End Function 

Function BinToDec(bstr) 
'convert 8 bit Binary number to Decimal 
    Dim j, Out As Integer 

    Out = 0 
    For j = 1 To 8 
     Out = Out + bstr(j) * 2^(j - 1) 
    Next j 

    BinToDec = Out 
End Function 

Мой код тест PHP:

protected function HexToBin($hstr) { 
    //convert hex string to binary string 
    $cnvarr = array(
     '0000', 
     '0001', 
     '0010', 
     '0011', 
     '0100', 
     '0101', 
     '0110', 
     '0111', 
     '1000', 
     '1001', 
     '1010', 
     '1011', 
     '1100', 
     '1101', 
     '1110', 
     '1111' 
    ); 
    $bstr = ""; 
    for ($i = 1; $i <= strlen($hstr); $i++) { 
     $hdgt = substr($hstr, $i, 1); 
     $cix = intval($hdgt); 
     echo $cix.'|'; 
     $bstr .= $cnvarr[$cix]; 
    } 
    return $bstr; 
} 

protected function createHash($data) { 
    //$OutBinStr = $this->HexToBin($data); 
    $OutBinStr = hex2bin($data); 

    $OutBinArr = array(); 
    $crc = array(); 

    //Convert string to array, LSB = OutBinArr(1) 
    for ($i = 1; $i <= 56; $i++) { 
     $OutBinArr[57 - $i] = substr($OutBinStr, $i - 1, 1); 
    } 

    //initialize crc 
    for ($i = 1; $i <= 8; $i++) { 
     $crc[$i] = 0; 
    } 

    // calculate 
    for ($i = 1; $i <= 56; $i++) { 

     $CRCTemp = $crc[1]^$OutBinArr[$i]; 
     $crc[1] = $crc[2]; 
     $crc[2] = $crc[3]; 
     $crc[3] = $crc[4]^$CRCTemp; 
     $crc[4] = $crc[5]^$CRCTemp; 
     $crc[5] = $crc[6]; 
     $crc[6] = $crc[7]; 
     $crc[7] = $crc[8]; 
     $crc[8] = $CRCTemp; 
    } 

    return implode('', $crc); 
} 

Пример вызова:

$buttonId = '0000145D6E0F01'; 
echo $this->createHash($buttonId); 

Я благодарю вас, если у вас есть какие-либо идеи, почему сценарий не генерировать правильный crc.

Спасибо, хорошие приветы Майкла

ответ

0

Вашего HexToBin() генерировал неправильную строку. Цикл for для substr() начался с 1 вместо 0. См. substr manual.

Импланирование $ crc привело к обратному порядку битового порядка.

<?PHP  
function HexToBin($hstr){ 
    $hstr = str_replace(' ','',$hstr); 
    $hArr = str_split($hstr); 
    $bstr = ""; 
    foreach($hArr AS $c){ 
     $cix = sprintf("0x0{$c}"); 
     // echo sprintf("%04b|",hexdec($cix)); 
     $bstr .= sprintf("%04b",hexdec($cix)); 
    } 

    return $bstr; 
} 

function createHash($data){ 
    $OutBinStr = HexToBin($data); 
    $crc = array_fill(0,8,0); 
    $OutBinArr = array_reverse(str_split($OutBinStr)); 

    // calculate 
    foreach($OutBinArr AS $i){ 
     $CRCTemp = $crc[0]^$i; 
     $crc[0] = $crc[1]; 
     $crc[1] = $crc[2]; 
     $crc[2] = $crc[3]^$CRCTemp; 
     $crc[3] = $crc[4]^$CRCTemp; 
     $crc[4] = $crc[5]; 
     $crc[5] = $crc[6]; 
     $crc[6] = $crc[7]; 
     $crc[7] = $CRCTemp; 
    } 
    $crc = array_reverse($crc); 
    return implode('', $crc); 
} 

$buttonId = '00 00 14 5D 6E 0F 01';  // 59 => 3B 
// $buttonId = '12 AA 12 5F 14 A2 12 12'; // 109 => 6D 
$crc = bindec(createHash($buttonId)); 
printf("\n%d => %X",$crc,$crc); 
?> 
+0

спасибо! :) – Michael