Вы можете рассматривать строку (однобайтовый символ) как число с кодировкой base-256, где "\ x00" представляет 0, '' (пробел, то есть "\ x20") представляет 32 и так далее до "\ xFF" ", что представляет 255.
Представление только с номерами 0-9 можно выполнить, просто изменив представление на основание 10.
Обратите внимание, что "кодировка base64" на самом деле не является преобразованием базы . base64 разбивает входные данные на группы по 3 байта (24 бита) и выполняет базовое преобразование для этих групп индивидуально. Это хорошо работает, потому что число с 24 битами может быть представлено четырьмя цифрами в базе 64 (2 ^ 24 = 64 ^ 4).
Это более или менее то, что делает el.pescado - он разбивает входные данные на 8-битные куски, а затем преобразует число в базу 10. Однако этот метод имеет один недостаток относительно базы 64. кодирование - оно не корректно выравнивается по границе байта. Чтобы представить число с 8 битами (0-255 при отсутствии знака), нам нужно три цифры в базе 10. Однако самая левая цифра содержит меньше информации, чем остальные. Это может быть 0, 1 или 2 (для чисел без знака).
Цифра в базе 10 хранит биты log (10) / log (2). Независимо от того, какой размер порции вы выберете, вы никогда не сможете выровнять представления с 8-битными байтами (в смысле «выравнивания», которое я описал в предыдущем параграфе). Следовательно, наиболее компактное представление - это базовое преобразование (которое вы можете видеть, как если бы оно было «базовым кодированием» только с одним большим фрагментом).
Вот пример с bcmath .
bcscale(0);
function base256ToBase10(string $string) {
//argument is little-endian
$result = "0";
for ($i = strlen($string)-1; $i >= 0; $i--) {
$result = bcadd($result,
bcmul(ord($string[$i]), bcpow(256, $i)));
}
return $result;
}
function base10ToBase256(string $number) {
$result = "";
$n = $number;
do {
$remainder = bcmod($n, 256);
$n = bcdiv($n, 256);
$result .= chr($remainder);
} while ($n > 0);
return $result;
}
Для
$string = "Mary had a little lamb";
$base10 = base256ToBase10($string);
echo $base10,"\n";
$base256 = base10ToBase256($base10);
echo $base256;
получаем
36826012939234118013885831603834892771924668323094861
Mary had a little lamb
Поскольку каждая цифра кодирует только log(10)/log(2)=~3.32193
бит, ожидается, что число будет иметь тенденцию быть 140% длиннее (не на 200% длиннее, как было бы с ответом el.pescado).