Перевести формулу Excel в PHP, рассчитанную на преобразование шестнадцатеричного значения в конкретное десятичное значение.

Мой считыватель USB RFID UHD показывает серийный номер моих карт Mifare 1K в виде десятизначного шестнадцатеричного числа 0025733f4b, Затем это переводится как «11516203» в моей текущей системе доступа.

Android читает те же UID карт, что и 4b3f7325, который, по-видимому, обратен серийному номеру, считываемому USB RFID-считывателем.

Теперь мне нужно прочитать 4b3f7325переверните это 0025733f4b а затем сделайте расчет, который мне не подходит, и результат «11516203».

Я хотел бы сделать это на PHP.

идея

Я нашел удивительный файл XLS в формате HEX to DEC, который имеет довольно сложную формулу для меня.

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 $1stpart = $result;
// Then calculate seconds part
// AK2*AU2+AL2*AV2+AM2*AW2+AN2*AX2, should return 16203
// save as $2ndpart = $result;
// combine $endresult = $1stpart . $2ndpart;
// 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
Чтобы разблокировать лист, вам, вероятно, потребуется использовать обход VBA листа Execl, я так и сделал :).

========================== ОТВЕТ ======================= ================

    <?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;
?>

0

Решение

Десятичное число, которое вам нужно для системы управления доступом, похоже, является конкатенацией третьего последнего байта UID (в формате вывода считывателя USB RFID), представленного в виде 8-разрядного целого числа без знака без знака, объединенного с последними двумя байтами представленного UID. как 16-разрядное целое число без знака.

Как только у вас есть UID в виде шестнадцатеричной строки $true_hexВы могли бы использовать

$uid_dec = hexdec($true_hex);

чтобы преобразовать его в десятичное целое число. Затем вы захотите взять третий младший байт в качестве первой части:

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

Далее вы должны взять младшие 16 бит UID в качестве второй части:

$uid_dec_second = $uid_dec & 0x0FFFF;

Наконец, вы должны объединить обе части, чтобы получить желаемый выходной номер. Это зависит от того, как лист Excel объединяет 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);
1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]