Это просто простое отображение одного набора значений в другой набор значений. Процедура всегда одна и та же:
- Список всех возможных входных и выходных значений.
- Найти индекс входа.
- Вернуть значение из выходного списка по этому индексу.
Обратите внимание, что часто нет необходимости составлять реальный список (т.е. загружать все значения в некоторую структуру данных). Обычно вы можете вычислить значение для любого индекса по запросу. Этот случай ничем не отличается.
Представьте себе список всех возможных входных пар:
0 100'000, 1'000'000
1 100'000, 1'000'001
2 100'000, 1'000'002
...
K 100'000, 9'999'999
K+1 100'001, 1'000'000
K+2 100'001, 1'000'001
...
N-1 999'999, 9'999'998
N 999'999, 9'999'999
Для любой данной пары (a, b) вы можете вычислить ее индекс i в этом списке как так:
// Make a and b zero-based
a -= 100'000
b -= 1'000'000
i = a*1'000'000 + b
Преобразуйте i в основание 36 (AZ и 0-9 дают вам 36 символов), заполните слева нулями по мере необходимости 1 и вставьте пробел после четвертый di git.
encoded = addSpace(zeroPad(base36(i)))
Чтобы вернуться к входной паре:
Преобразуйте строку с 8-символьной базой 36 в базовую 10 (это индекс в списке, помните ), затем извлеките a и b из индекса.
i = base10(removeSpace(encoded))
a = i/1'000'000 + 100'000 // integer divison (i.e. ignore remainder)
b = i%1'000'000 + 1'000'000
Вот реализация в Go: https://play.golang.org/p/KQu9Hcoz5UH
1 Если вам не нравится идея нулевого заполнения, вы также можете сместить i на этом этапе. Целевой набор значений достаточно велик, вам нужно всего около 32% от всех чисел с основанием 36, состоящих из восьми или менее цифр.