sys-of-num
System of numeration
Преамбула
Часто возникает ситуация необходимости хранения чисел в формате более коротких строк, особенно часто это связано с метками времени или числовыми данными, предназначенными для формирования имен файлов например, которые не желательно использовать именно в виде чисел.
Данная библиотека позволяет кодировать числа в строковые значения используя как предопределенные наборы символов, так и пользовательские.
В данном случае вознимает вопрос - но почему бы не делать просто вот так:
(123456789).toString(16); // 75bcd15
???
Дело в том, что данный подход вернет строку в наборе символов:
0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f
... в то время, как библиотека позволяет переопределить набор, например так:
f,e,d,c,b,a,9,8,7,6,5,4,3,2,1,0 // 0 = "f", 15 = "0" (16 символов в наборе = 16-ричная система счисления)
... или так:
9,8,7,6,5,4,3,2,1,0,a,b,c,d,e,f // 0 = "9", 15 = "f" (16 символов в наборе = 16-ричная система счисления)
... или даже так:
9,8,7,6,5,4,3,2,1,0,+,a,b,c,d,e,f,- // 0 = "9", 17 = "-" (18 символов в наборе = 18-ричная система счисления)
Товарищ, как насчет побаловаться 128-ричной системой счисления? Необычной 73-ричной? М?
Система счисления
Система счисления определяется в момент создания экземпляра библиотеки как длинна массива переданных символов. То есть при установке набора символов a, b, c, d, e, f система счисления будет определена как 6-ричная.
Предопределенные наборы символов
x64ascii
-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz
x64friendly
0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-_
Два данных набора различаются положением символов dash и underscore, что как следствие влияет на их вес. Так в первом случае dash равнозначен нулю, а во втором он равен 62.
Предопределение двух таких наборов связано с тем, что в ascii символ dash идет до символов чисел, а underscore между строчными и прописными буквами, таким образом для выравнивания закодированных строк в файловых системах (если брать данные строки как имена файлов или каталогов) с использованием в кодировке этих символов необходимо в качестве нуля использовать dash (чтобы такой файл/каталог был ранее в выдаче, чем файл/каталог начинающийся с символа ноль), что тем не менее непривычно для человека. Второй набор x64friendly более дружественен человеку (0 = "0"), но именованные через него строки не будут верно выравниваться в файловых системах.
x62
0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
x52
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
x52revert
zyxwvutsrqponmlkjihgfedcbaZYXWVUTSRQPONMLKJIHGFEDCBA
Данные наборы имеют зеркальные наборы символов, так в x52 нулем будет являться "A", а в x52revert нулем будет "z".
x38ascii
-0123456789_abcdefghijklmnopqrstuvwxyz
x38friendly
0123456789abcdefghijklmnopqrstuvwxyz-_
Положение символов dash и underscore аналогично наборам x64ascii и x64friendly c той лиш разницей, что в данных наборах отсутствуют заглавные буквы, то есть данные наборы совместимы с системой Windows, в которой невозможно рядом создать два файла с именами например "A" и "a".
x36
abcdefghijklmnopqrstuvwxyz
x26
abcdefghijklmnopqrstuvwxyz
x26revert
zyxwvutsrqponmlkjihgfedcba
Аналогично наборам x52 и x52revert.
Примеры использования
Создание экземпляра библиотеки
const sysOfNum = require('sys-of-num');
const son = sysOfNum.create();
В случае, если в метод create не передан набор символов или имя предопределенного набора символов, то в качестве набора символов будет установлен набор "x62", являющийся набором по умолчанию.
Получение информации о разрядности установленного набора
son.getSystem(); // 62
Получение информации о наборе
son.getSymbols(); // <массив набора символов>
Получение предопределенного набора по имени
son.getSymbolsSetByName(name); // <предопределенный набор name> или пустой массив
Установка набора символов при создании экземпляра
const son = sysOfNum.create(); // Установка набора символов по умолчанию (х62)
const son = sysOfNum.create('x52'); // Установка набора символов x52
const son = sysOfNum.create(['a', 'b', 'c']); // Установка пользовательского набора и соответственно троичная система счисления
const son = sysOfNum.create('qwerty'); // Неизвестное имя набора будет интерпретировано как набор ['q', 'w', 'e', 'r', 't', 'y']
В момент установки набора определяется и его система счисления.
Переопределение набора символов
Аналогично установке набора символов при инициации.
son.setSymbols();
son.setSymbols('x52');
son.setSymbols(['a', 'b', 'c']);
son.setSymbols('qwerty');
Кодирование
son.encode();
В случае, если в метод encode не передано число - в качестве числа будет использована текущая метка времени, то есть Date.now().
son.encode(199999999999); // Для набора x52 вернет результат "KGBmJCH", а для набора x52revert "ptyNqxs".
Раскодирование
// При наборе x52
son.decode("KGBmJCH"); // 199999999999
// При наборе x52revert
son.decode("ptyNqxs"); // 199999999999
Пример кодирования в 128-ричную систему и обратно числа 199999999999
const sysOfNum = require('sys-of-num');
const son = sysOfNum.create(); // В данный момент в экземпляре установлен набор символов по умолчанию x62
// Пользовательский набор например
const mySweetSymbols = "абвгдеёжзийклмнопрстуфхцчшщъыьэюяАБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ".split('');
// Устанавливаем набор экземпляра как x62 расширенный пользовательским набором
// получаем 62 символа + 66 символов = 128-ричная система
son.setSymbols([].concat(son.getSymbolsSetByName('x62'), mySweetSymbols));
// Кодируем / раскодируем
son.encode(199999999999); // 5Й7tVЯ
son.decode("5Й7tVЯ"); // 199999999999
Попробуй, это прикольно
npm run test
Фиатюресы
Думаю добавить возможность создания пользовательских алгоритмов замусоривания результирующих строк и соответственно декодер дописать с учетом возможного замусоривания в строке (для конспирации).