Как преобразовать биты из Python в php?

У меня есть этот шестнадцатеричный код F0C2CA89012A04008C0000000000000000000000 от устройства. Этот шестнадцатеричный код показывает стоимость капель воды.

В моем коде Python

msg = F0C2CA89012A04008C0000000000000000000000
msg_counters = bytes.fromhex(msg)[5:20] 
# output: b'*\x04\x00\x8c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'      
msg_counters_int = int.from_bytes(msg_counters)
# output: 218157641024778742068286256301735936    
bin_string = '{:0120b}'.format(msg_counters_int)
print(bin_string)

это напечатает значение битов. Эти биты показывают ценность воды

001010100000010000000000100011000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

00101 = 5
01000 = 8
00010 = 2

Я пытаюсь преобразовать код в PHP и застреваю int.from_bytes из Python. Я не знаю, как преобразовать значение. В моем PHP-коде

$a = hex2bin("F0C2CA89012A04008C0000000000000000000000");
$b = substr($a, 5, 20);
// output: b"*\x04\x00Œ\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"

Я пытался использовать функцию unpack, но она не показывает правильное значение.

NameError: name 'F0C2CA89012A04008C0000000000000000000000' is not defined — укажите действительный код.
Thierry Lathuille 31.07.2024 09:14
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
1
50
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Чтобы преобразовать этот код Python в PHP, вам необходимо выполнить манипуляции с шестнадцатеричными строками, нарезку байтов и преобразование целых чисел. Вот как вы можете добиться эквивалента в PHP:

Код Python

msg = "F0C2CA89012A04008C0000000000000000000000"
msg_counters = bytes.fromhex(msg)[5:20]
msg_counters_int = int.from_bytes(msg_counters)
bin_string = '{:0120b}'.format(msg_counters_int)
print(bin_string)

Эквивалентный PHP-код

<?php
$msg = "F0C2CA89012A04008C0000000000000000000000";

// Convert hex string to binary data
$msg_counters = hex2bin(substr($msg, 5, 30)); // Get the binary data from hex string

// Convert binary data to integer
$msg_counters_int = gmp_init(bin2hex($msg_counters), 16); // GMP for handling large integers

// Convert integer to binary string with leading zeros
$bin_string = str_pad(gmp_strval($msg_counters_int, 2), 120, '0', STR_PAD_LEFT);

echo $bin_string;
?>

Объяснение:

  1. Преобразование шестнадцатеричного кода в двоичный:

    • hex2bin(substr($msg, 5, 30)) преобразует соответствующую часть шестнадцатеричной строки в двоичные данные. substr($msg, 5, 30) извлекает подстроку, начиная с 6-го символа (индекс 5) и длиной 30 символов.
  2. Преобразование двоичного числа в целое число:

    • bin2hex($msg_counters) преобразует двоичные данные в шестнадцатеричные.
    • gmp_init(bin2hex($msg_counters), 16) инициализирует число GMP (GNU Multiple Precision) из шестнадцатеричной строки, поскольку целочисленный тип PHP может не обрабатывать очень большие числа.
  3. Целое число в двоичную строку:

    • gmp_strval($msg_counters_int, 2) преобразует номер GMP в двоичную строку.
    • str_pad(..., 120, '0', STR_PAD_LEFT) гарантирует, что двоичная строка имеет ведущие нули, соответствующие длине 120 бит.

Этот фрагмент кода PHP обеспечивает результат, эквивалентный коду Python, преобразуя указанный сегмент шестнадцатеричной строки в двоичную строку с ведущими нулями.

Вы заметили, что ответ, сгенерированный вашим кодом, отличается от ответа, упомянутого в вопросе? Можете ли вы объяснить разницу?

KIKO Software 31.07.2024 09:04

Большое спасибо. Я не очень хорошо разбираюсь в функциональности битов. Я изучу код, на который вы ответили. Значение bin_string не совпадает с выводом Python, но я могу подстроить значение вашего вывода. это ваш вывод, и перед пунктирной линией я могу подставить значение 10101000100100000001 ----001010100000010000000000100011000000‌​00000000000000000000‌​0000000000000000 0000‌​00000000000000000000‌​0000

user3391620 31.07.2024 09:16

@user3391620 user3391620 «Я изучу код, на который вы ответили». Обратите внимание, что принятие ответа означает для людей, которые столкнутся с ним позже, что он действительно отвечает на вопрос, поэтому вам всегда следует не торопиться и проверять, что он действителен, прежде чем делать это.

Thierry Lathuille 31.07.2024 10:15
Ответ принят как подходящий

Вот альтернативное решение, которое основано не на расширении GMP, а на стандартной функции base_convert(). Для каждого байта две шестнадцатеричные цифры извлекаются из входной строки и преобразуются в базу 2:

function getBits(string $msg, int $from, int $to)
{
    $bits = '';
    for($i=$from; $i<$to; $i++)
    {
        $s = base_convert(substr($msg, 2*$i, 2), 16, 2);
        $bits .= str_pad($s, 8, '0', STR_PAD_LEFT);
    }
    return $bits;
}

echo getBits('F0C2CA89012A04008C0000000000000000000000', 5, 20);

Выход:

001010100000010000000000100011000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

Другие вопросы по теме