Как закодировать 5-6 значное число в 3х символьную буквенно-числовую последовательность и с обратным декодированием?

Ссылка скопирована
PHP
1 ответ

Есть QR-коды c закодированным URL:
https://domen/XXXXXX
XXXXXX - числа: 56789, 89567, 129087 и т.д.

хочется закодировать эти 5-6 значные числа в буквенно-числовую последовательность не длиннее 3 символов, т.е. чтобы к примеру из
4f9 получать 56789
а из kh9 например 129087

таким образом решив сразу две задачи:
- уменьшение длины кодируемой в QR-коде строки (чтобы QR-код лучше читался при маленьких размерах)
- скрытие чисел XXXXXX алгоритмом сжатия аля шифрования )))

Есть что-нибудь такое в PHP ? Или как придумать какую-нибудь свою такую функцию (алгоритм) чтобы можно было кодировать и раскодировать эти числа?

Дополнительно:

https://3v4l.org/REX9l

  • гениальное решение - спасибо!
  • единственный минус, но думаю что я смогу его как-то решить - нужно как-то решить вопрос с перебором:
    47901 > mCL 47902 > mCM 47903 > mCN 47904 > mCO 47905 > mCP 47906 > mCQ 47907 > mCR 47908 > mCS 47909 > mCT 47910 > mCU 47911 > mCV

    47901 > mCL 47902 > mCM 47903 > mCN 47904 > mCO 47905 > mCP 47906 > mCQ 47907 > mCR 47908 > mCS 47909 > mCT 47910 > mCU 47911 > mCV

    т.е. у меня еще стоит задача не только сжать, но и немного зашифровать, чтобы потенциальный злоумышленник не смог поняв схему последовательности перебирать разные варианты в прямом порядке - понятно что просто перебирать он сможет - но чтобы хотя бы как-то результат был непредсказуем )

  • хотя наверное просто перемешать массив можно и это уже циферно-буквенную последовательность сломает:
    function encodeNumber(int $number): string {     // Символы, используемые для кодирования     static $array = null;     if (!$array) {         $array = [...range('a', 'z'), ...range('A', 'Z'), ...range(0, 9)];         shuffle($array);     }     $charset = join('', $array);     $base = strlen($charset); // Определение основания системы счисления     $encoded = '';      // Преобразование числа в заданную систему счисления     while ($number > 0) {         $remainder = $number % $base;         $encoded = $charset[$remainder] . $encoded;         $number = (int) ($number / $base);     }      return $encoded; }

    function encodeNumber(int $number): string { // Символы, используемые для кодирования static $array = null; if (!$array) { $array = [...range('a', 'z'), ...range('A', 'Z'), ...range(0, 9)]; shuffle($array); } $charset = join('', $array); $base = strlen($charset); // Определение основания системы счисления $encoded = ''; // Преобразование числа в заданную систему счисления while ($number > 0) { $remainder = $number % $base; $encoded = $charset[$remainder] . $encoded; $number = (int) ($number / $base); } return $encoded; }

  • Леонид, ну лучше тогда задать строкой сразу, потому что у тебя сломается расшифровка при динамичном перемешивании
    $charset = '!@#$%^&*()_+=-50beIzOux1iHnX42Y9vjEgAKcaURs3F8Jm6trQwDCTfMBPoZLkWpNh7SdyqlGV';

    $charset = '!@#$%^&*()_+=-50beIzOux1iHnX42Y9vjEgAKcaURs3F8Jm6trQwDCTfMBPoZLkWpNh7SdyqlGV';

Ответы:

Вот тут алгоритм: https://programforyou.ru/calculators/number-systems
Согласно https://www.ietf.org/rfc/rfc3986.txt можно использовать символы 0-9, a-z, A-Z - . _ ~, т.е. получаем 66 знаков, или 287496 значений для трехсимвольной строки, что недостаточно для всех 6значных чисел, а вот все 5значные вполне уместятся.

Дополню ответы выше
, можно хранить существующие строки из символов и назначать им цифровые идентификаторы
Например
1: hsgeiV
2: jsksGs
И так далее
Хранить это в бд или файле и при запросе искать пару
На все варианты вам не хватит трехсимвольной строки, вы можете удалять старые неактуальные кода или расширить диапазон

base64 не рассматривали?

  • пробовали смотреть на результат например base64_encode('56789') - что там на выходе получается? NTY3ODk= - это далеко не 3и символа )))
  • base64 не числа жи кодирует
  • Леонид, надо просто не строку, а байты туда пихать

Ну, три символа - это вы "очень много кушать", а 4 - без проблем
php.net/base_convert

999 999 в 36 ричной системе дает 4 символа с латиницей. Единственное - расширить алфавит, и расширить основание системы. Т.е. смотрите в сторону систем исчисления с большим основанием (64 например точно хватит)

https://calculatori.ru/perevod-chisel.html

  • 64 это очень плохая идея
  • Ипатьев, в URL не полезет?
  • Леонид, а какая разница? я вижу, вы уже нашли ответ на свой вопрос
  • 64 точно не хватит, 64^3 = 262144
Нужно решить такую задачу?

Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.

Заказать помощь
Лучший ответ
1
Мария Код Ответ

Для кодирования 5-6 значного числа в 3х символьную буквенно-числовую последовательность и обратного декодирования можно использовать следующий подход:

1. Преобразование числа в строку:
Для начала необходимо преобразовать числовое значение в строку. Например, если у нас есть число 123456, то мы можем преобразовать его в строку "123456".

2. Деление строки на подстроки:
Затем разбиваем строку на три равные части. В нашем случае, строка "123456" будет разбита на три подстроки: "123", "456".

3. Кодирование каждой подстроки:
Далее каждую подстроку можно закодировать в буквенно-числовую последовательность. Например, можно преобразовать каждую цифру в соответствующую букву (например, 1 - A, 2 - B и т.д.). Таким образом, подстрока "123" может быть закодирована как "ABC".

4. Объединение закодированных подстрок:
Наконец, объединяем закодированные подстроки в одну строку. В итоге, из числа 123456 мы получим закодированную строку "ABCDEF".

5. Декодирование:
Для обратного декодирования мы просто проходим обратно в противоположном направлении. Разбиваем закодированную строку на три равные части, декодируем каждую подстроку обратно в числовое значение и объединяем их. Таким образом, строка "ABCDEF" будет декодирована обратно в число 123456.

Пример кодирования и декодирования числа 123456:

<?php
function encodeNumber($number) {
$str = strval($number);
$part1 = chr(intval($str[0]) + 65);
$part2 = chr(intval($str[1]) + 65);
$part3 = chr(intval($str[2]) + 65);

return $part1 . $part2 . $part3;
}

function decodeString($encodedString) {
$part1 = ord($encodedString[0]) - 65;
$part2 = ord($encodedString[1]) - 65;
$part3 = ord($encodedString[2]) - 65;

return intval($part1 . $part2 . $part3);
}

$number = 123456;
$encoded = encodeNumber($number);
$decoded = decodeString($encoded);

echo "Encoded: " . $encoded . "

Другие ответы (0)

Пока нет других ответов. Будьте первым, кто поможет автору.

Ответить на вопрос

комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Вам также может быть интересно