Verify - строка закодирована в base64 python

Есть ли хороший способ проверить, закодирована ли строка в base 64 с помощью python?

Ответ 1

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

Ответ 2

import base64
import binascii

try:
    base64.decodestring("foo")
except binascii.Error:
    print "no correct base64"

Ответ 3

Я искал решение той же проблемы, а потом мне в голову попала очень простая. Все, что вам нужно сделать, это декодировать, а затем перекодировать. Если перекодированная строка равна закодированной строке, то она кодируется в base64.
Вот код:

import base64

def isBase64(s):
    try:
        return base64.b64encode(base64.b64decode(s)) == s
    except Exception:
        return False

Вот оно!

Редактировать: здесь версия функции, которая работает как с строковыми, так и с байтовыми объектами в Python 3:

import base64

def isBase64(sb):
        try:
                if isinstance(sb, str):
                        # If there any unicode here, an exception will be thrown and the function will return false
                        sb_bytes = bytes(sb, 'ascii')
                elif isinstance(sb, bytes):
                        sb_bytes = sb
                else:
                        raise ValueError("Argument must be string or bytes")
                return base64.b64encode(base64.b64decode(sb_bytes)) == sb_bytes
        except Exception:
                return False

Ответ 4

если длина закодированной строки равна 4, ее можно декодировать

base64.encodestring("whatever you say").strip().__len__() % 4 == 0

так что вам просто нужно проверить, может ли строка соответствовать чему-то вроде выше, тогда она не будет вызывать никаких исключений (I Guess =. =)

if len(the_base64string.strip()) % 4 == 0:
    # then you can just decode it anyway
    base64.decodestring(the_base64string)

Ответ 5

def is_base64(s):
    s = ''.join([s.strip() for s in s.split("\n")])
    try:
        enc = base64.b64encode(base64.b64decode(s)).strip()
        return enc == s
    except TypeError:
        return False

В моем случае у моего ввода s появились символы новой строки, которые мне пришлось разделить перед сравнением.

Ответ 6

@geoffspear верен в том смысле, что это не на 100% возможно, но вы можете довольно близко подойти, проверив заголовок строки, чтобы убедиться, что он совпадает с заголовком строки, закодированной в base64 (re: Как проверить, закодирована ли строка в base64 или нет).

# check if a string is base64 encoded.
def isBase64Encoded(s):
    pattern = re.compile("^([A-Za-z0-9+/]{4})*([A-Za-z0-9+/]{4}|[A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{2}==)$")
    if not s or len(s) < 1:
        return False
    else:
        return pattern.match(s)

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

Ответ 7

Решение, которое я использовал, основано на одном из предыдущих ответов, но использует более актуальные звонки.

В моем коде my_image_string - это либо сами данные изображения в необработанном виде, либо строка base64. Если декодирование не удается, то я предполагаю, что это необработанные данные.

Обратите внимание на ключевое слово validate=True для b64decode. Это необходимо для того, чтобы декодер генерировал утверждение. Без этого не будет жалоб на незаконную строку.

import base64, binascii

try:
    image_data = base64.b64decode(my_image_string, validate=True)
except binascii.Error:
    image_data = my_image_string

Ответ 8

x = 'possibly base64 encoded string'
result = x
try:
   decoded = x.decode('base64', 'strict')
   if x == decoded.encode('base64').strip():
       result = decoded
except:
   pass

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