将 Excel 公式转换为 PHP 计算,用于将 HEX 转换为特定的十进制值

Translate Excel formula to PHP calculation meant for HEX conversion to specific decimal value

我的 USB RFID UHD reader 将我的 Mifare 1K 卡的序列号显示为 10 位十六进制数 0025733f4b。然后在我当前的访问系统中转换为“11516203”。

Android读取的卡片UID与4b3f7325一样,好像是USB RFID读取序列号的倒序reader.

我现在需要阅读 4b3f7325,将其反转为 0025733f4b,然后进行超出我能力范围的计算,结果为“11516203”。

我想在 PHP 中完成此操作。

想法

我找到了一个 HEX 到 DEC 的令人惊叹的 XLS 文件,它对我来说有一个非常复杂的公式。

CELL    -   VALUE

C2      -   0025733f4b
R2      -   =AI2*AW2+AJ2*AX2
T2      -   =AK2*AU2+AL2*AV2+AM2*AW2+AN2*AX2

R2 CALCULATION RESULT = AI2*AW2+AJ2*AX2 = 115
T2 CALCULATION RESULT = AK2*AU2+AL2*AV2+AM2*AW2+AN2*AX2 = 16203

这给了我“11516203”。

---Start of R2 calc---
AI2 = = SUM(16^(ROW(INDIRECT("b1:a"&LEN(Y2)))-1)*(MATCH(LEFT(RIGHT(0&Y2,ROW(INDIRECT("b1:a"&LEN(Y2)))),1),{"0";"1";"2";"3";"4";"5";"6";"7";"8";"9";"A";"B";"C";"D";"E";"F"},0)-1))
Needs Y2 =MID(C2,5,1)
--------------------
AW2 = 16
--------------------
AJ2 = =SUM(16^(ROW(INDIRECT("b1:a"&LEN(Z2)))-1)*(MATCH(LEFT(RIGHT(0&Z2,ROW(INDIRECT("b1:a"&LEN(Z2)))),1),{"0";"1";"2";"3";"4";"5";"6";"7";"8";"9";"A";"B";"C";"D";"E";"F"},0)-1))
Needs Z2 =MID(C2,6,1)
--------------------
AX2 = 1
---End of R2 calc---

---Start of T2 calc---
AK2 =SUM(16^(ROW(INDIRECT("b1:a"&LEN(AA2)))-1)*(MATCH(LEFT(RIGHT(0&AA2,ROW(INDIRECT("b1:a"&LEN(AA2)))),1),{"0";"1";"2";"3";"4";"5";"6";"7";"8";"9";"A";"B";"C";"D";"E";"F"},0)-1))
Needs AA2 =MID(C2,7,1)
--------------------
AU2=4096
--------------------
AL2 =SUM(16^(ROW(INDIRECT("b1:a"&LEN(AB2)))-1)*(MATCH(LEFT(RIGHT(0&AB2,ROW(INDIRECT("b1:a"&LEN(AB2)))),1),{"0";"1";"2";"3";"4";"5";"6";"7";"8";"9";"A";"B";"C";"D";"E";"F"},0)-1))
Needs AB2 =MID(C2,8,1)
--------------------
AV2=256
--------------------
AM2 =SUM(16^(ROW(INDIRECT("b1:a"&LEN(AC2)))-1)*(MATCH(LEFT(RIGHT(0&AC2,ROW(INDIRECT("b1:a"&LEN(AC2)))),1),{"0";"1";"2";"3";"4";"5";"6";"7";"8";"9";"A";"B";"C";"D";"E";"F"},0)-1))
Needs AC2 =MID(C2,9,1)
--------------------
AW2=16
--------------------
AN2 =SUM(16^(ROW(INDIRECT("b1:a"&LEN(AD2)))-1)*(MATCH(LEFT(RIGHT(0&AD2,ROW(INDIRECT("b1:a"&LEN(AD2)))),1),{"0";"1";"2";"3";"4";"5";"6";"7";"8";"9";"A";"B";"C";"D";"E";"F"},0)-1))
Needs AD2 =MID(C2,10,1)
--------------------
AX2=1

然后我尝试将公式从 Excel 转换为 PHP,这就是我现在的位置:

<?php
$wrong_hex = "4b3f7325";
echo 'Input HEX from Android = '.$wrong_hex.'<br>';

$done2 = array_reverse(str_split($wrong_hex, 2));
array_unshift($done2, '00');
$true_hex = implode("",$done2);
echo 'True Hex on Mifare1k card (after php reverse): '.$true_hex.'<br>'; // this is where i get the reversed value

echo '<br>Parts of Formula that ive figured out<br>';

$AA2 = $true_hex[6];
$AB2 = $true_hex[7];
$AC2 = $true_hex[8];
$AD2 = $true_hex[9];
$Y2 = $true_hex[4];
$Z2 = $true_hex[5];
$AV2 = 256;
$AW2 = 16;
$AU2 = 4096;
$AX2 = 1;
$AJ2 = '';
$AI2 = '';
$AM2 = '';
$AK2 = '';
$AL2 = '';
$AN2 = '';

echo 'AA2 = '. $AA2 .'<br>';
echo 'AB2 = '. $AB2.'<br>';
echo 'AC2 = '. $AC2.'<br>';
echo 'AD2 = '. $AD2.'<br>';
echo 'Y2 = '. $Y2.'<br>';
echo 'Z2 = '. $Z2.'<br>';
echo 'AV2 = '. $AV2.'<br>';
echo 'AW2 = '. $AW2.'<br>';
echo 'AU2 = '. $AU2.'<br>';
echo 'AX2 = '. $AX2;


// Calculate first part from AI2*AW2+AJ2*AX2, should return 115
// save as stpart = $result;
// Then calculate seconds part
// AK2*AU2+AL2*AV2+AM2*AW2+AN2*AX2, should return 16203
// save as ndpart = $result;
// combine $endresult = stpart . ndpart;
// Then i will do PDO Select WHERE idcard = $endresult ?>

结果

Input HEX from Android = 4b3f7325
True Hex on Mifare1k card (after php reverse): 0025733f4b

Parts of Formula that ive figured out
AA2 = 3
AB2 = f
AC2 = 4
AD2 = b
Y2 = 7
Z2 = 3
AV2 = 256
AW2 = 16
AU2 = 4096
AX2 = 1

据我所知,我只需要知道如何计算 1:**

SUM(16^(ROW(INDIRECT("b1:a"&LEN(Y2)))-1)*(MATCH(LEFT(RIGHT(0&Y2,ROW(INDIRECT("b1:a"&LEN(Y2)))),1),{"0";"1";"2";"3";"4";"5";"6";"7";"8";"9";"A";"B";"C";"D";"E";"F"},0)-1))

然后我可以做一些功能什么的。您可以在此处获取 XLS:https://www.i-keys.de/download_free/Hexa.xls 要解锁 sheet 你可能需要使用 Execl sheet VBA 旁路,我就是这样做的:).

========================== 答案============= ==========================

    <?php
    $wrong_hex = "4b3f7325";
    $done2 = array_reverse(str_split($wrong_hex, 2));
    array_unshift($done2, '00');
    $true_hex = implode("",$done2);
    echo 'From Android : ' . $wrong_hex . '<br>';
    echo 'Reversed TRUE HEX : ' . $true_hex . '<br>'; // this is where i get the reversed value

    $uid_dec = hexdec($true_hex);
    $uid_dec_first = ($uid_dec & 0x0FF0000) >> 16;
    $uid_dec_second = $uid_dec & 0x0FFFF;
    $uid_touse = $uid_dec_first . $uid_dec_second;

    echo 'Your Security ID is '. $uid_touse;
?>

门禁系统所需的十进制数似乎是 UID(USB RFID reader 输出格式)倒数第三个字节的串联,表示为串联的 8 位无符号十进制整数UID 的最后两个字节表示为 16 位无符号十进制整数。

一旦您将 UID 作为十六进制字符串 $true_hex,您就可以使用

$uid_dec = hexdec($true_hex);

将其转换为十进制整数。然后你会想把第三个最低字节作为第一部分:

$uid_dec_first = ($uid_dec & 0x0FF0000) >> 16;

接下来,将UID的低16位作为第二部分:

$uid_dec_second = $uid_dec & 0x0FFFF;

最后,您将连接两个部分以获得所需的输出数字。这取决于 Excel sheet 如何连接 R2 和 T2(我在你的问题中没有找到)。通常,这可以是

$uid_accesscontrol = sprintf("%03d%05d", $uid_dec_first, $uid_dec_second);

或者干脆

$uid_accesscontrol = $uid_dec_first . $uid_dec_second;

请注意,在 Android 上,您可以轻松地进行转换:

byte[] uid = tag.getId();
int uid_first = uid[2] & 0x0FF;
int uid_second = ((uid[1] & 0x0FF) << 8) | (uid[0] & 0x0FF);
String serial = String.format("%03d%05d", uid_first, uid_second);