Две кодировки Base64 дают одинаковое декодирование

Ожидается ли поведение, когда два кодирования могут отображаться в одно и то же декодирование? Я пытаюсь устранить проблему с цифровой подписью, выполняя проверки работоспособности промежуточных строк в кодировке base64.

Например, следующая кодировка base64:

R0VUDQoNCg0KRnJpLCAwNCBTZXAgMjAwOSAxMTowNTo0OSBHTVQrMDA6MDANCi8=

а также:

R0VUCgoKRnJpLCAwNCBTZXAgMjAwOSAxMDozMzoyOCBHTVQrMDA6MDAKLw==

оба декодируют:

GET


Fri, 04 Sep 2009 11:05:49 GMT+00:00
/

(С экранированными символами это: GET\n\n\n Fri, 04 Sep 2009 11:05:49 GMT+00:00\n/)

Первая кодировка получена в результате тестирования двух онлайн-кодировщиков base64.

Вторая кодировка исходит из кодировщика Objective-C base64, доступного здесь.

Что-то не так с результатом, который я генерирую с помощью кодировщика Obj-C?


person Alex Reynolds    schedule 04.09.2009    source источник


Ответы (5)


Понятно, что закодированные строки имеют одинаковые шаблоны там, где они соответствуют буквенно-цифровым символам, и разные там, где они соответствуют разрывам строк. Таким образом, разница в том, что где-то на пути «Кодировать» -> «Декодировать» программное обеспечение обрабатывает разрывы строк (CR (\ r), LF (\ n) или CRLF (\ r \ n)) по-разному, и поэтому у вас есть такие полученные результаты.

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

person sharptooth    schedule 04.09.2009

Другой пример, чтобы доказать, что строки не равны, используя Python:

>>> from base64 import decodestring as d
>>> a = "R0VUDQoNCg0KRnJpLCAwNCBTZXAgMjAwOSAxMTowNTo0OSBHTVQrMDA6MDANCi8="
>>> b = "R0VUCgoKRnJpLCAwNCBTZXAgMjAwOSAxMDozMzoyOCBHTVQrMDA6MDAKLw=="
>>> d(a)
'GET\r\n\r\n\r\nFri, 04 Sep 2009 11:05:49 GMT+00:00\r\n/'
>>> d(b)
'GET\n\n\nFri, 04 Sep 2009 10:33:28 GMT+00:00\n/'
>>> d(a) == d(b)
False

Более длинная строка использует разрывы строки CRLF, более короткая — простые LF.

person Ferdinand Beyer    schedule 04.09.2009
comment
+1 за четкий ответ и за быстрый ответ на Python. :-) - person Quinn Taylor; 04.09.2009

На самом деле, они не декодируются в одно и то же.

$ echo 'R0VUCgoKRnJpLCAwNCBTZXAgMjAwOSAxMDozMzoyOCBHTVQrMDA6MDAKLw==' | base64 -d | hexdump 
0000000 4547 0a54 0a0a 7246 2c69 3020 2034 6553
0000010 2070 3032 3930 3120 3a30 3333 323a 2038
0000020 4d47 2b54 3030 303a 0a30 002f          
000002b
$ echo 'R0VUDQoNCg0KRnJpLCAwNCBTZXAgMjAwOSAxMTowNTo0OSBHTVQrMDA6MDANCi8=' | base64 -d | hexdump
0000000 4547 0d54 0d0a 0d0a 460a 6972 202c 3430
0000010 5320 7065 3220 3030 2039 3131 303a 3a35
0000020 3934 4720 544d 302b 3a30 3030 0a0d 002f
000002f
person moonshadow    schedule 04.09.2009

Как предложил @sharptooth, разрывы строк \r\n в первом, \n во втором.

>>> base64.b64decode("R0VUDQoNCg0KRnJpLCAwNCBTZXAgMjAwOSAxMTowNTo0OSBHTVQrMDA6MDANCi8=")
'GET\r\n\r\n\r\nFri, 04 Sep 2009 11:05:49 GMT+00:00\r\n/'
>>> base64.b64decode("R0VUCgoKRnJpLCAwNCBTZXAgMjAwOSAxMDozMzoyOCBHTVQrMDA6MDAKLw==")
'GET\n\n\nFri, 04 Sep 2009 10:33:28 GMT+00:00\n/'
person Mark Rushakoff    schedule 04.09.2009

Суть в том, что строки base 64 декодируются в последовательности байтов, а не в символы. Сравнение массивов байтов, созданных каждой из ваших строк с основанием 64, показывает, что разница заключается в том, как выполняется завершение строки: везде, где первая имеет 13, за которой следует 10, вторая имеет только 10. Это стандартная Windows-против- Разница завершения строки Unix.

person AakashM    schedule 04.09.2009