2013-12-23 4 views
0

Есть ли смысл идеи хранить большие числа в виде букв? Например, допустим, что у меня (относительно небольшой) номер 138201162401719, и я хочу уменьшить количество символов (я знаю, что это не помогает с сохранением дискового пространства) до наименьшего количества символов. В английском алфавите есть 26 букв (но я считаю их 25, так как нам нужна нулевая буква). Если я начинаю разделив мой большое количество на куски, каждый из 25 или менее я получаю:Преобразование больших чисел в буквы (и обратно)

13, 8, 20, 11, 6, 24, 0, 17, 19

Если я затем подсчитать число алфавита а = 0, Ь = 1, с = 2, d = 3 ... Я могу преобразовать это:

NIULGYART

Так я пошел от 15 цифр длинный (138201162401719) до 9 символов долго (NIULGYART). Разумеется, это можно было бы легко преобразовать обратно в исходное число.

Итак ... мой первый вопрос: «ли это иметь имя» и мой второй «Кто-нибудь есть код PHP, который будет делать преобразование (в обоих направлениях)?»

Я ищу подходящую терминологию, чтобы заниматься своими исследованиями в Google ... хотя примеры рабочего кода тоже классные.

+0

Как вы планируете хранить свои номера перед конверсией, как число или строку. ($ num = "138201162401719" или $ num = 138201162401719) – rullof

+0

Слово, которое вы ищете, является «кодировкой». –

ответ

2

Это возможно только в том случае, если вы планируете хранить свой номер перед обработкой в ​​виде строки. Потому что вы не можете хранить огромное число как целые числа. Вы потеряете точность (13820116240171986468445 будет сохранен как 1.3820116240172E+22), так что многие цифры будут потеряны.

Если вы планируете хранить число в виде строки, это будет ваш ответ:

Функция, используемая: intval, chr и preg_match_all.

<?php 

$regex = '/(2[0-5])|(1[0-9])|([0-9])/'; 
$numberString = '138201162401719'; 

preg_match_all($regex, $numberString, $numberArray, PREG_SET_ORDER); 

echo($numberString . " -> "); 

foreach($numberArray as $value){ 
    $character = chr (intval($value[0]) + 65); 
    echo($character); 
} 

?> 

Demo

Это результат:

138201162401719 -> NIULGYART

1

Вот как я бы это сделать:

  • Хранить большое число в виде строки и разделить его на массив чисел, содержащих по одной цифре каждый
  • Петли через вытяжной массив 2-значные куски с помощью substr()
  • Проверьте, если число меньше 26 (в этом случае, это алфавит) и добавить их в массив
  • Использования array_map() с chr() создать новый массив символов из приведенного выше массива
  • Implode результирующего массива, чтобы получить шифр

в коде:

$str = '138201162401719'; 
$arr = str_split($str); 
$i = 0; // starting from the left 

while ($i < count($arr)) { 
    $n = substr($str, $i, 2); 
    $firstchar = substr($n, 0, 1); 
    if ($n < 26 && $firstchar != 0) { 
     $result[] = substr($str, $i, 2); 
     $i += 2; // advance two characters 
    } else { 
     $result[] = substr($str, $i, 1); 
     $i++;  // advance one character 
    } 
}  

$output = array_map(function($n) { 
    return chr($n+65); 
}, $result); 

echo implode($output); // => NIULGYART 

Demo.

1

В качестве альтернативы, можно преобразовать входной целое число, чтобы выразить ее в базе 26, вместо того, чтобы основание 10. Нечто подобное (псевдокод):

func convertBase26(num) 
    if (num < 0) 
    return "-" & convertBase26(-num) // '&' is concatenate. 
    else if (num = 0) 
    return "A" 
    endif 
    output = ""; 
    while (num > 0) 
    output <- ('A' + num MOD 26) & output // Modulus operator. 
    num <- num DIV 26 // Integer division. 
    endwhile 
    return output 
endfunc 

При этом используется А = 0, В = 1, до Z = 25 и стандартным обозначением места: 26 = BA. Очевидно, что базовое преобразование легко обратимо.

0

Я пытался сделать то же самое в PHP без успеха.

Предполагая, что я использую 26 букв английского алфавита, начиная с А = 0 до Z, как 25:

Я нахожу самую высокую мощность 26 ниже числа я кодирующим. Я делю его на лучшую силу, которую я нашел. Из результата я забираю целое число, преобразовываю его в букву и умножаю десятичные числа на 26. Я продолжаю делать это, пока не получу целое число. Это нормально, чтобы получить ноль, поскольку это A, но если он имеет десятичные значения, он должен быть умножен.

За 1 миллиард, который равен DGEHTYM, и это делается в 6 циклах, очевидно. Хотя мой ответ демонстрирует, как кодировать, я боюсь, что это не поможет делать это на PHP, и это то, что я пытаюсь сделать сам. Я надеюсь, что алгоритм помогает людям там.

Смежные вопросы