Преобразование двоичного числа в базовое 64

#php #base64

#php #base64

Вопрос:

Я знаю, что это довольно глупый вопрос, но я не знаю, что делать.

У меня есть произвольное двоичное число, скажем,

 1001000000110010000000100100000010000011000000010001000001011000110000110000011100011100000011000000010010011000100000000000000100100000010110001100001000000111
  

Я хочу преобразовать его в базовое 64 с помощью PHP — и каждый мой способ дает мне другой результат. Даже разные онлайн-конвертеры преобразуют его по-разному:

http://home2.paulschou.net/tools/xlate/
http://convertxy.com/index.php/numberbases/

PHP base_convert работает только до base36, а base64_encode ожидает строку.

Что мне делать?

ОБНОВЛЕНИЕ: я реализовал функции решения, предложенные @binaryLV, и это сработало хорошо.

Однако я сравнил результаты со встроенным в PHP base_convert. Оказалось, что base_convert в base36 возвращает меньшие значения, чем пользовательская функция base64! (И да, я добавлял ‘1’ ко всем двоичным числам, чтобы гарантировать, что начальные нули не будут потеряны).

Я также заметил, что base_convert довольно неточно работает с большими числами. Итак, мне нужна функция, которая работает как base_convert, но точно и, желательно, до базового 64.

Комментарии:

1. 1) Хотите, чтобы число было преобразовано в базовое 64 напрямую? — 2) хотите, чтобы двоичное число сначала преобразовывалось в ASCII, а затем в базовое 64? 3) или что?

2. @Mido — Я действительно не вижу никакой разницы между (1) и (2) — для меня важен результат. Я хочу иметь возможность последовательно преобразовывать двоичное число (а не строку из ‘0’ и ‘1’) в базовое 64, а затем иметь возможность конвертировать его обратно в двоичное.

Ответ №1:

Длина строки в примере равна 160. Это заставляет меня думать, что оно содержит информацию о 160/8 символах. Итак,

  1. разделить строку на части, каждая часть содержит 8 двоичных цифр и описывает один символ
  2. преобразуйте каждую часть в десятичное целое число
  3. создайте строку из символов, которые сделаны из кодов ASCII со 2-го шага

Это будет работать со строками с размером n*8 . Для других строк (например, 12 двоичных цифр) это даст неожиданные результаты.

Код:

 function bin2base64($bin) {
    $arr = str_split($bin, 8);
    $str = '';
    foreach ( $arr as $binNumber ) {
        $str .= chr(bindec($binNumber));
    }
    return base64_encode($str);
}

$bin = '1001000000110010000000100100000010000011000000010001000001011000110000110000011100011100000011000000010010011000100000000000000100100000010110001100001000000111';
echo bin2base64($bin);
  

Результат:

 kDICQIMBEFjDBxwMBJiAASBYwgc=
  

Здесь также есть функция для декодирования его обратно в строку двоичных цифр:

 function base64bin($str) {
    $result = '';
    $str = base64_decode($str);
    $len = strlen($str);
    for ( $n = 0; $n < $len; $n   ) {
        $result .= str_pad(decbin(ord($str[$n])), 8, '0', STR_PAD_LEFT);
    }
    return $result;
}

var_dump(base64bin(bin2base64($bin)) === $bin);
  

Результат:

 boolean true
  

Комментарии:

1. Я думаю, это подойдет. Спасибо (:

2. @egasimus, я также добавил декодер , так что вы можете конвертировать их обоими способами. Не стесняйтесь проголосовать за ответ, если он вам нравится 🙂 Ах, и я забыл предупредить, что длина строки должна быть n*8 , т. Е. Строка с 12 двоичными числами даст неожиданные результаты.

3. Извините, что не принял ваш ответ — я сравнил вашу функцию с base_convert в base36; для ‘100000011111110100000000’ ваша функция возвращает ‘gf0AAA ==’, а base_convert (36) возвращает ’52L8G’ (или ‘bets’ без последних 4 нулей, которые являются просто дополнением). Так что, очевидно, есть лучшее решение, и я полон решимости его найти. 🙂

4. @egasimus, я получаю «gf0A», а не «GF0AA ==». Также было бы легче помочь, если бы вы сказали, чего именно вы пытаетесь достичь, поскольку «лучшее решение» — это очень общий термин. Например, 100% согласованные и надежные результаты кажутся мне достаточно хорошим решением.

5. Это хорошо работает. Если вы хотите избежать знаков =, просто убедитесь, что число 0 и 1 кратно 24 (8 бит на символ ASCII и 6 бит на базовый 64 символа). равенства появляются, когда вы создаете последний символ в base64, но у вас нет праваколичество бит.

Ответ №2:

PHP имеет встроенную функцию кодирования base 64, смотрите Документацию здесь . Если вы хотите получить десятичное значение двоичной строки, сначала используйте bin2dec, кстати, есть аналогичные функции для шестнадцатеричных чисел. Документация — ваш друг здесь.

[ПРАВИТЬ]

Возможно, я неправильно понял ваш вопрос, если вы хотите преобразовать между фактическими базами (база 2 и 64), используйте base_convert

Комментарии:

1. base_convert() не является точным с большими числами, он даже не может обрабатывать 32-битные числа в 32-битной системе. bin2dec() также не следует использовать для больших чисел.

2. @binaryLV: действительно, согласно предупреждению на странице функции на PHP.net

Ответ №3:

 $number = 1001000000110010000000100100000010000011000000010001000001011000110000110000011100011100000011000000010010011000100000000000000100100000010110001100001000000111;
echo base64_encode ($number);
  

Это если вы хотите, чтобы точная строка была преобразована в базовое 64.

Комментарии:

1. Здесь $number интерпретируется как десятичное число, а не двоичное.

Ответ №4:

Чтобы преобразовать двоичное число (основание 2) в основание 64, используйте base_convert функцию.

 $number = 1001000000110010000000100100000010000011000000010001000001011000110000110000011100011100000011000000010010011000100000000000000100100000010110001100001000000111;
base_convert ($number , 2, 64);
  

Комментарии:

1. base_convert принимает только аргументы от 2 до 36 включительно.

2. @Meglio Так и есть. Я, вероятно, должен был заметить это, когда я ответил на это.