Base64 der кодировки в чем разница

Base64 der кодировки в чем разница

mabu 2016-05-22T00:46:54+07:00

Base64 буквально означает — позиционная система счисления с основанием 64. Здесь 64 — это число символов в алфавите кодирования, из которого формируется конечный буквенно‐цифровой текст на основе латинского алфавита. Число соответствует наибольшей степени двойки (2^6), которая может быть представлена с использованием печатных символов ASCII.

Зачем это нужно?

Так исторически сложилось, что многие форматы передачи и хранения данных (html, url схемы, xml, email и тому подобное) используют текст вместо бинарных кодов. Но если формат передачи данных текстовый, а передать необходимо бинарные данные (отдельно либо вместе с текстовыми данными) — тут на помощь приходит base64. Например:

  • data: URL схемы для изображений в CSS, HTML;
  • передача картинок и других данных внутри XML, не используя внешние файлы;
  • хранение изображений в базах данных;
  • вложения в электронной почте;
  • сертификаты, шифрование и электронные подписи.

И это не исчепывающий список, где применяется base64.

Алгоритм

Алгоритм кодирования прост. Берётся тройка октетов. 3 откета по 8 бит — это 24 бита. С другой стороны 24 бита — это 4 раза по 6 бит. Получившиеся четыре шестибитных числа представляют индексы символов в следующей строке:

Для примера закодируем строку «Man» в base64.

Исходные данные: строка «Man»

Коды символов: 77 97 110

Двоичный вид с группировкой по 8 бит: 0 1 0 0 1 1 0 1 0 1 1 0 0 0 0 1 0 1 1 0 1 1 1 0

Двоичный вид с группировкой по 6 бит: 0 1 0 0 1 1 0 1 0 1 1 0 0 0 0 1 0 1 1 0 1 1 1 0

Полученные индексы в base64: 19 22 5 46

Конечный результат в Base64: T W F u

Если длина результирующей строки не кратна четырём, то её дополняют необходимым количеством символов «=».

Где же код?

Довольно теоретизирований, перейдём к коду.

Заголовочный файл base64.bi:

Код FreeBASIC
‘ Кодирование в Base64 и обратно
#ifndef unicode
&t; #define unicode
#endif
#include once "windows.bi"
#include once "winshlwapi.bi"

Const B64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
Const Base64StringLength As Integer = 19

‘ Шифрует массив байт в base64
‘ sOut — указатель на буфер под результирующую строку
‘ sEncodedB — указатель на массив байт, которые нужно закодировать
‘ BytesCount — количество байт в массиве
‘ Функция может записать за выделенный буфер, если он будет слишком мал
‘ Размер требуемого буфера под результирующую строку должен быть не менее ((BytesCount 3) + 1) * 4 символов + 1 символ под нулевой
‘ Функция записывает завершающий ноль
‘ Возвращает количество символов (без учёта завершающего нуля)
Declare Function Encode64( _
&t;&t; ByVal sOut As WString Ptr , _
&t;&t; ByVal sEncodedB As UByte Ptr , _
&t;&t; ByVal BytesCount As Integer _
) As Integer

‘ Дешифрует из base64 в массив байт
‘ b — указатель на буфер, куда будет записан результат дешифровки
‘ s — указатель на base64‐строку
‘ Возвращает количество записанных в буфер байт
‘ Размер буфера должен быть достаточным для записи в него данных
Declare Function Decode64( _
&t;&t; ByVal b As UByte Ptr , _
&t;&t; ByVal s As WString Ptr _
) As Integer

Код FreeBASIC
#include once "base64.bi"

Function E0( ByVal v1 As UByte ) As UByte
&t; ‘ Получить шесть левых бит числа
&t; Return v1 Shr 2
End Function

Function E1( ByVal v1 As UByte , ByVal v2 As UByte ) As UByte
&t; ‘ Получить два правых бита первого числа и четыре левых бита второго числа
&t; Return ((v1 And &b00000011) Shl 4) + (v2 Shr 4)
End Function

Читайте также:  Генератор для пьезоизлучателя схема

Function E2( ByVal v2 As UByte , ByVal v3 As UByte ) As UByte
&t; ‘ Получить четыре правых бита первого числа и два левых бита второго числа
&t; Return ((v2 And &b00001111) Shl 2) + (v3 Shr 6)
End Function

Function E3( ByVal v3 As UByte ) As UByte
&t; ‘ Получить шесть правых бит числа
&t; Return v3 And &b00111111
End Function

Function Encode64( ByVal sOut As WString Ptr , ByVal sEncodedB As UByte Ptr , ByVal BytesCount As Integer ) As Integer
&t; Dim j As Integer = 0
&t; Dim k As Integer = 0
&t; ‘ Количество байт, не умещающихся в тройку байт
&t; Dim ELM3 As Integer = BytesCount Mod 3
&t; ‘ Идти через каждые три байта
&t; For j = 0 To BytesCount — ELM3 — 1 Step 3
&t;&t;sOut[k + 0] = (@B64 + E0(sEncodedB[j + 0]))[0]
&t;&t;sOut[k + 1] = (@B64 + E1(sEncodedB[j + 0], sEncodedB[j + 1]))[0]
&t;&t;sOut[k + 2] = (@B64 + E2(sEncodedB[j + 1], sEncodedB[j + 2]))[0]
&t;&t;sOut[k + 3] = (@B64 + E3(sEncodedB[j + 2]))[0]
&t;&t;k += 4
&t; Next

&t; Select Case ELM3
&t;&t; Case 1
&t;&t;&t;sOut[k + 0] = (@B64 + E0(sEncodedB[j + 0]))[0]
&t;&t;&t;sOut[k + 1] = (@B64 + E1(sEncodedB[j + 0], sEncodedB[j + 1]))[0]
&t;&t;&t;sOut[k + 2] = &h3D
&t;&t;&t;sOut[k + 3] = &h3D
&t;&t;&t;k += 4
&t;&t; Case 2
&t;&t;&t;sOut[k + 0] = (@B64 + E0(sEncodedB[j + 0]))[0]
&t;&t;&t;sOut[k + 1] = (@B64 + E1(sEncodedB[j + 0], sEncodedB[j + 1]))[0]
&t;&t;&t;sOut[k + 2] = (@B64 + E2(sEncodedB[j + 1], sEncodedB[j + 2]))[0]
&t;&t;&t;sOut[k + 3] = &h3D
&t;&t;&t;k += 4
&t; End Select
&t; ‘ Поставить завершающий ноль
&t;sOut[k] = 0
&t; Return k
End Function

Function GetBase64Index( ByVal sChar As Integer ) As Integer
&t; If sChar = 0 Then
&t;&t; Return -1
&t; End If
&t; Dim w As WString Ptr = StrChr(@B64, sChar)
&t; If w = 0 Then
&t;&t; Return -1
&t; End If
&t; Return w — @B64
End Function

‘ Пропускаем все символы не из набора
Function SkipWrongChar( ByVal s As WString Ptr ) As Integer
&t; Dim i As Integer = 0
&t; Dim sChar As Integer = s[i]
&t; Do Until sChar = 0
&t;&t; If GetBase64Index(sChar) <> -1 Then
&t;&t;&t; Exit Do
&t;&t; End If
&t;&t;i += 1
&t;&t;sChar = s[i]
&t; Loop
&t; Return i
End Function

Function CalculateString( ByVal b As UByte Ptr , ByVal BytesCount As Integer , ByVal w1 As Integer , ByVal w2 As Integer , ByVal w3 As Integer , ByVal w4 As Integer ) As Integer
&t; If w2 > -1 Then
&t;&t;b[BytesCount] = (w1 * 4 + w2 16) And 255
&t;&t;BytesCount += 1
&t; End If
&t; If w3 > -1 Then
&t;&t;b[BytesCount] = (w2 * 16 + w3 4) And 255
&t;&t;BytesCount += 1
&t; End If
&t; If w4 > -1 Then
&t;&t;b[BytesCount] = (w3 * 64 + w4) And 255
&t;&t;BytesCount += 1
&t; End If
&t; Return BytesCount
End Function

Function Decode64( ByVal b As UByte Ptr , ByVal s As WString Ptr ) As Integer
&t; Dim BytesCount As Integer = 0
&t; Dim length As Integer = Len (*s)
&t; For i As Integer = 0 To length — 1 Step 4
&t;&t; Dim ww As Integer = Any
&t;&t; ‘ Необходимо пропустить все символы не из набора
&t;&t;i += SkipWrongChar(s[i + 0])
&t;&t; If i >= length — 0 Then
&t;&t;&t; Return BytesCount
&t;&t; End If
&t;&t;ww = s[i + 0]
&t;&t; Dim w1 As Integer = GetBase64Index(ww)

Читайте также:  Ошибка запуска игры error code 0xc0000225 crossfire

&t;&t;i += SkipWrongChar(s[i + 1])
&t;&t; If i >= length — 1 Then
&t;&t;&t; Return CalculateString(b, BytesCount, w1, 0, 0, 0)
&t;&t; End If
&t;&t;ww = s[i + 1]
&t;&t; Dim w2 As Integer = GetBase64Index(ww)

&t;&t;i += SkipWrongChar(s[i + 2])
&t;&t; If i >= length — 2 Then
&t;&t;&t; Return CalculateString(b, BytesCount, w1, w2, 0, 0)
&t;&t; End If
&t;&t;ww = s[i + 2]
&t;&t; Dim w3 As Integer = GetBase64Index(ww)

&t;&t;i += SkipWrongChar(s[i + 3])
&t;&t; If i >= length — 3 Then
&t;&t;&t; Return CalculateString(b, BytesCount, w1, w2, w3, 0)
&t;&t; End If
&t;&t;ww = s[i + 3]
&t;&t; Dim w4 As Integer = GetBase64Index(ww)

&t;&t;BytesCount = CalculateString(b, BytesCount, w1, w2, w3, w4)
&t; Next
&t; Return BytesCount
End Function

Использование

Функция Encode64 кодирует массив байт в base64‐строку. Для этого ей нужно передать указатель буфер под результирующую строку, указатель на массив байт и размер массива.

Код FreeBASIC
#ifndef unicode
#define unicode
#endif
‘ Для преобразования строки из utf-16 в utf-8
#include once "windows.bi"

Const BufferLength As Integer = 1024
Const StringToConvert = "Всем привет! Это сообщение будет закодировано."

‘ Строка, куда будет записана base64‐строка, плюс один символ под нулевой
Dim base64 As WString * (BufferLength + 1) = Any

‘ Массив байт
Dim bytes(BufferLength * SizeOf ( WString )) As UByte = Any

‘ Нужно получить из строки массив байт
‘ Для этого её нужно преобразовать в utf-8
Dim BytesCount As Integer = WideCharToMultiByte(CP_UTF8, 0, @StringToConvert, -1, @bytes(0), BufferLength * SizeOf ( WString ), 0, 0) — 1

‘ Закодировать массив байт в bas64
Encode64(@base64, @bytes(0), BytesCount)
Print base64

‘ Преобразовать из base64 в массив байт
BytesCount = Decode64(@bytes(0), @base64)

‘ Из массива байт в строку, результат будет в base64
bytes(BytesCount) = 0
MultiByteToWideChar(CP_UTF8, 0, @bytes(0), -1, base64, BufferLength)
Print base64

В примере используются функции WideCharToMultiByte и MultiByteToWideChar для преобразования строки в массив байт и обратно. Если у тебя есть уже заранее оформленный массив байт, например, данные файла, то эти функции использовать не нужно. В качестве домашнего задания предлагаю написать простую утилиту, кодирующую и декодирующую любые файлы в base64.

Поделись ссылочкой в социальных сетях

«Пакетные файлы» создали этот сайт по технологии XHTML 11 марта 2016 года

Как работает кодировка Base64

Кодирование Base64 дает возможность для отправки всех типов данных через электронную почту в Интернете.

Если Интернет является информационной магистралью, то в случае с электронной почтой имеются ограничения. Через нее могут передаваться только небольшие данные.

Транспортная система электронной почты предназначена только для обычного ASCII текста. Попытка отправить текст на других языках или произвольные файлы — это как получить грузовик через овраг.

При попытке отправить текст на других языках или отправить случайный файл — это как попытаться проехать на большом грузовике через маленькое ущелье.

Так как же проехать на грузовике через это маленькое ущелье?

Мы должны разобрать наш грузовик на части и переправить эти части с одного конца на другой.

То же самое происходит, когда вы отправляете вложения по электронной почте. В процессе, известном как кодирование, двоичные данные преобразуются в текст ASCII, который можно без проблем транспортировать по электронной почте. В конце пути данные декодируются и мы получаем исходный файл.

Читайте также:  Водонагреватель термекс ошибка е3 как устранить

Одним из методов кодирования данных в виде обычного текста ASCII является Base64.

Это один из способов, используемых стандартом MIME для отправки данных, отличных от обычного текста.

Base64 в помощь

Кодирование Base64 занимает три байта, каждый из которых состоит из восьми битов, и представляет их в виде четырех печатных символов в стандарте ASCII. По сути, делается это в два шага.

Первым шагом является преобразование трех байтов в четыре числа из шести бит. Каждый символ в стандарте ASCII состоит из семи битов. Base64 использует только 6 бит (что соответствует 2 ^ 6 = 64 символам), чтобы гарантировать, что закодированные данные могут быть пригодны для печати и читаемы "по-человечески".

Ни один из специальных символов, доступных в таблице ASCII, не используется. 64 символа (отсюда и название Base64) — это 10 цифр, 26 символов в нижнем регистре, 26 символов в верхнем регистре, а также символы "+" и "/".

Например, три байта равны 155, 162 и 233, соответствующий (и пугающий) поток битов равен 100110111010001011101001, который, в свою очередь, соответствует 6-битовым значениям 38, 58, 11 и 41.

Эти цифры преобразуются в символы из таблицы ASCII на втором шаге с использованием таблицы "Base64 encoding". 6-битные значения нашего примера преобразуются в последовательность ASCII "m6Lp".

  • 155 -> 10011011
  • 162 -> 10100010
  • 233 -> 11101001
  • 100110 -> 38
  • 111010 -> 58
  • 001011 -> 11
  • 101001 -> 41
  • 38 -> m
  • 58 -> 6
  • 11 -> L
  • 41 -> p

Этот двухэтапный процесс применяется ко всей последовательности байтов, которые закодированы. Чтобы гарантировать, что закодированные данные могут быть правильно напечатаны и не превышают ограничения почтового сервера, символы новой строки добавляются так, чтобы общая длина строк не превышала 76 символов. Символы новой строки кодируются, как и все остальные данные.

Решение

В процессе кодирования мы можем столкнуться с проблемой. Если размер исходных данных в байтах кратен трем, все работает нормально. Если это не так, мы можем получить один или два 8-битных байта. Однако для правильного кодирования нам нужно ровно три байта.

Решение состоит в том, чтобы добавить достаточно байтов со значением "0" для создания 3-байтовой группы. Два таких значения добавляются, если у нас есть один дополнительный байт данных, один добавляется для двух дополнительных байтов.

Конечно, эти искусственные завершающие "0" не могут быть закодированы, используя таблицу кодирования ниже. Они должны быть представлены 65-м символом.

Отступом Base64 является "=". Естественно, он может появляться только в конце закодированных данных.

Зарегистрируйтесь, чтоб продолжить пользоваться всеми функциями Techfeed

Популярные теги

В чем преимущество использованияBase64 кодировать?

Я хотел бы понять это лучше. Мне действительно это нужно? Разве я не могу просто использовать чистые строки?

Я слышал, что кодировка может быть до 30% больше, чем оригинал (по крайней мере, для изображений).

Ответы на вопрос ( 8 )

Популярные вопросы

Установите свою любимую песню в качестве мелодии звонка для Iphone

Проблема c импортом классов в WebDriverIo js

МОИ КНОПКИ ОТ ВАС НЕ ШАРЯТ, ХОТЯ ГОД НАЗАД ВСЕ БЫЛО НОРМАЛЬНО?

Ссылка на основную публикацию
Amd raidxpert2 tech что это
Приветствую. AMD-RAIDXpert2 Tech — опция в биосе, предназначена для создания RAID-массива из твердотельных накопителей с интерфейсом NMVe (порт M.2), подключенных...
Adblock detector