base64
Pythonを使用して文字列がエンコードされているかどうかを確認する良い方法はありますか?
11 に答える
私は同じ問題の解決策を探していましたが、非常に単純な問題が頭に浮かびました。デコードしてから再エンコードするだけです。再エンコードされた文字列がエンコードされた文字列と等しい場合、base64でエンコードされます。
コードは次のとおりです。
import base64
def isBase64(s):
try:
return base64.b64encode(base64.b64decode(s)) == s
except Exception:
return False
それでおしまい!
編集:これは、Python3の文字列オブジェクトとバイトオブジェクトの両方で機能する関数のバージョンです。
import base64
def isBase64(sb):
try:
if isinstance(sb, str):
# If there's 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
import base64
import binascii
try:
base64.decodestring("foo")
except binascii.Error:
print "no correct base64"
これは不可能です。最善の方法は、文字列が有効なBase 64であるかどうかを確認することですが、ASCIIテキストのみで構成される多くの文字列はBase64であるかのようにデコードできます。
私が使用したソリューションは、以前の回答の1つに基づいていますが、より最新の呼び出しを使用しています。
私のコードでは、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
エンコードされた文字列の長さが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)
@geoffspearは、これが100%可能ではないという点で正しいですが、文字列ヘッダーをチェックして、base64でエンコードされた文字列のヘッダーと一致するかどうかを確認することでかなり近づけることができます(文字列が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を返したいと思っていました。
PythonRegExの使用
import re
txt = "VGhpcyBpcyBlbmNvZGVkIHRleHQ="
x = re.search("^([A-Za-z0-9+/]{4})*([A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{2}==)?$", txt)
if (x):
print("Encoded")
else:
print("Non encoded")
私はほぼ8年遅れていることを知っていますが、正規表現を使用できるため、特定の入力がBASE64であるかどうかを確認できます。
import re
encoding_type = 'Encoding type: '
base64_encoding = 'Base64'
def is_base64():
element = input("Enter encoded element: ")
expression = "^([A-Za-z0-9+/]{4})*([A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{2}==)?$"
matches = re.match(expression, element)
if matches:
print(f"{encoding_type + base64_encoding}")
else:
print("Unknown encoding type.")
is_base64()
デコードを試みる前に、私は最初にフォーマットチェックを実行するのが好きです。これは、最も軽量なチェックであり、誤検知を返さないため、フェイルファストコーディングの原則に従います。
このタスクのユーティリティ関数は次のとおりです。
RE_BASE64 = "^([A-Za-z0-9+/]{4})*([A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{2}==)?$"
def likeBase64(s:str) -> bool:
return False if s is None or not re.search(RE_BASE64, s) else True
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
は、比較の前に削除しなければならない改行が含まれていました。
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だけに入れられます。デコードしてみても、常に機能するとは限りません。