Как закодировать 5-6 значное число в 3х символьную буквенно-числовую последовательность и с обратным декодированием?
Есть 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
т.е. у меня еще стоит задача не только сжать, но и немного зашифровать, чтобы потенциальный злоумышленник не смог поняв схему последовательности перебирать разные варианты в прямом порядке - понятно что просто перебирать он сможет - но чтобы хотя бы как-то результат был непредсказуем )
- хотя наверное просто перемешать массив можно и это уже циферно-буквенную последовательность сломает:
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';
Ответы:
Вот тут алгоритм: 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
Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.
Пока нет других ответов. Будьте первым, кто поможет автору.
Ответить на вопрос
Для кодирования 5-6 значного числа в 3х символьную буквенно-числовую последовательность и обратного декодирования можно использовать следующий подход:
1. Преобразование числа в строку:
Для начала необходимо преобразовать числовое значение в строку. Например, если у нас есть число 123456, то мы можем преобразовать его в строку "123456".
2. Деление строки на подстроки:
Затем разбиваем строку на три равные части. В нашем случае, строка "123456" будет разбита на три подстроки: "123", "456".
3. Кодирование каждой подстроки:
Далее каждую подстроку можно закодировать в буквенно-числовую последовательность. Например, можно преобразовать каждую цифру в соответствующую букву (например, 1 - A, 2 - B и т.д.). Таким образом, подстрока "123" может быть закодирована как "ABC".
4. Объединение закодированных подстрок:
Наконец, объединяем закодированные подстроки в одну строку. В итоге, из числа 123456 мы получим закодированную строку "ABCDEF".
5. Декодирование:
Для обратного декодирования мы просто проходим обратно в противоположном направлении. Разбиваем закодированную строку на три равные части, декодируем каждую подстроку обратно в числовое значение и объединяем их. Таким образом, строка "ABCDEF" будет декодирована обратно в число 123456.
Пример кодирования и декодирования числа 123456: