#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 символах. Итак,
- разделить строку на части, каждая часть содержит 8 двоичных цифр и описывает один символ
- преобразуйте каждую часть в десятичное целое число
- создайте строку из символов, которые сделаны из кодов 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 Так и есть. Я, вероятно, должен был заметить это, когда я ответил на это.