Base64 декодировать, пока нет Base64 - PullRequest
1 голос
/ 22 октября 2010

Так что моя проблема, я думаю, очень проста.Мне нужно декодировать Base64, пока нет Base64, я проверяю с помощью RegEx, есть ли Base64, но у меня нет идеи, как декодировать, пока нет Base64.

В этом коротком коде я могу декодировать Base64пока не будет Base64, потому что мой текст определен.(Пока материал декодирования Base64 не будет декодированием "Hello World")

# Import Libraries
from base64 import *
import re

# Text & Base64 String
strText = "Hello World"
strEncode = "VmxSQ2ExWXlUWGxUYTJoUVVqSlNXRlJYY0hOT1ZteHlXa1pLVVZWWE9EbERaejA5Q2c9PQo=".encode("utf-8")

# Decode
objRgx = re.search('^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$', strEncode.decode("utf-8"))

strDecode = b64decode(objRgx.group(0).encode("utf-8"))

print(strDecode.decode("utf-8"))

while strDecode != strText.encode("utf-8"):
    strDecode = b64decode(strDecode)

    print(strDecode.decode("utf-8"))

У кого-нибудь есть идея, как я могу декодировать Base64, пока не появится реальный текст (больше не base64)

PS извините за мой плохой английский.

Ответы [ 4 ]

6 голосов
/ 22 октября 2010

Вы не можете, не в произвольном смысле. Проблема просто в том, что каждый день слова тоже могут быть BASE64. Таким образом, нет никакого реального способа определить разницу между ними.

BASE64 не имеет терминатора, кроме длины. Это МОЖЕТ быть прекращено с помощью = или ==, но не ДОЛЖНО быть прекращено. = Просто дополняют. Заполнение не требуется, то нет =. Поэтому вполне возможно, что BASE64 закончится и начнется какой-то текст, и вы не сможете его обнаружить.

Отредактируйте для «Значит, действительно нет способа сделать то, что я хочу?»:

Нет, не детерминистически, не достоверно. Даже при использовании эвристики возможны случаи, когда он не будет работать, и вы в конечном итоге будете использовать слишком много символов, что приведет к мусору в конце вашего двоичного блока и потере символов в следующем текстовом потоке.

Теперь это для произвольного блока BASE64. Если вы ЗНАЕТЕ, что такое двоичные данные, тогда, возможно, есть надежда.

Например, если вы ЗНАЕТЕ, что такое двоичные данные, большинство двоичных форматов «знают», когда они «сделаны». Я не знаю действительного двоичного формата, который говорит: «Читай, пока не достигнешь EOF». Как правило, они содержат внутренние дескрипторы «это то, сколько данных имеет следующий блок» или терминаторы, говорящие «Я закончил».

В этих случаях вы можете рассматривать BASE64 как поток. BASE64 в основном довольно прост. Он занимает 3 байта и преобразует их в 4 символа.

Итак, потоковый ридер B64 должен просто прочитать 4 символа и вернуть 3 байта, которые они представляют.

Если у вас есть, скажем, программа чтения PNG, она может начать читать преобразованный поток. И когда он «готов», он «закрывает» поток, и ваш исходный текст «в конце BASE64».

Может также работать, если вы знаете размер оригинального вложения. Если кто-то отправил «10 000 байт», то вы используете потоковый декодер BASE64 и просто читаете из него «10 000 байт».

Чаще всего BASE64 будет иметь терминатор = или ==. Это случаи, когда вы этого не делаете, это проблема. Декодированный поток работает в любом случае.

Если вы не знаете исходный размер вложения или формат закодированного бинарного файла, то вам почти не повезло.

2 голосов
/ 22 октября 2010

В качестве эвристики вы можете вычислить среднюю длину слова в результате. На естественном языке будут короткие слова, такие как «Как эвристика, вы можете посмотреть длину слова». Строка, которая все еще закодирована в Base64, будет иметь мало пробелов и длинные строки между пробелами.

В качестве другой эвристики вы можете рассчитать пропорции гласных (a, e, i, o, u) по отношению к согласным или количество заглавных букв в середине слов.

0 голосов
/ 01 января 2018

Здесь я вижу два ценных ответа, относящихся к средней длине слова (Марк Люттон) и байтовому размеру исходных данных (Уилл Хартунг).Еще одна полезная вещь: ищите словарные слова ожидаемых, значащих цифр и / или дат.

0 голосов
/ 22 октября 2010

То есть вы имеете дело с блоком данных, который, возможно, неоднократно кодировался в base64? Почему бы просто не зациклить строку через b64decode (), пока она не выдаст ошибку, тогда?

Также я думаю, что вам, вероятно, не нужно разбрызгивать столько .encode("utf-8") вокруг.

...