понедельник, 18 марта 2019 г.

Как закодировать последовательность байт в BASE64

При передаче данных применяются открытые стандартные форматы кодирования. Один из наиболее часто применяемых это формат кодирования BASE64. Рассмотрим, как это кодирование может быть выполнено в MUMPS.

Для кодирования в формат BASE64 исходная последовательность байт делится на тройки байт, которые рассматриваются как число. Первый байт тройки считается старшим байтом числа, второй средним и третий младшим. После чего рассматриваются 4 группы битов этого числа по 6 бит. Каждая группа битов считается номером символа и этот символ выводится.

Таким образом из 3-х исходных байт получается 4 байта, при этом выходная последовательность кодируется 6-ти битами и может быть представлена как текстовая последовательность из символов множества "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".

Если последняя тройка входных символов неполная, то в выходную последовательность по определенному правилу добавляются 1 или 2 символа "=".

Спецификация кодирования определена в RFC 1421 и RFC 2045.

Выходную последовательность традиционно форматируют порциями по 64 символа. Для этого надо читать входную последовательность по 64/4*3=48 байт.

В MiniM Database Server поддерживается встроенная функция $zcvt с опцией выходного представления "base64", используя которую, можно кодировать в формат "base64" и обратно.

Используя ее, кодирование строки выглядит:
ENCINT(str)
 q $zcvt(str,"O","base64")
То же самое на стандартном MUMPS без использования расширенных функций может выглядеть, например, так:
ENCODE(str)
 n ret,i,num,n,part,enc,arr
 s arr="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
 s ret=""
 ; step up to 3 bytes
 f i=1:3:$l(str) d
 . ; get part and calculate depending of part's length
 . s part=$e(str,i,i+2)
 . ; initial accumulators
 . s enc="",num=0
 . ; calculate total number
 . f n=1:1:$l(part) s num=num*256+$a(part,n)
 . f n=n+1:1:3 s num=num*256
 . ; calculate padding symbols
 . f n=1:1:3-$l(part) s enc=enc_"=" s num=num\64
 . ; calculate encoded bytes
 . f n=1:1:$l(part)+1 s enc=$e(arr,num#64+1)_enc s num=num\64
 . s ret=ret_enc
 q ret
Для кодирования последовательности, например значения глобала или данных из устройства ввода, программисту достаточно организовать чтение порциями по 48 байт и запись получающихся текстовых строк в выходную последовательность.

Комментариев нет:

Отправить комментарий