web-dev-qa-db-ja.com

base64文字列から等号を削除しても大丈夫ですか?

スペースを節約するためにbase64にエンコードしている文字列があります。最後に等号を削除すると大したことですか?これにより、エントロピーが大幅に減少しますか?結果の文字列の長さを確実に固定するにはどうすればよいですか?

>>> base64.b64encode(combined.digest(), altchars="AB")
'PeFC3irNFx8fuzwjAzAfEAup9cz6xujsf2gAIH2GdUM='

ありがとう。

21
ensnare

あなたのコードを見てください:

_>>> base64.b64encode(combined.digest(), altchars="AB")
'PeFC3irNFx8fuzwjAzAfEAup9cz6xujsf2gAIH2GdUM='
_

Base64でエンコードされている文字列は、digest()という関数の結果です。ダイジェスト関数が固定長の値を生成している場合(たとえば、MD5またはSHA1ダイジェストを計算している場合)、b64encodeへのパラメーターは常に同じ長さになります。

上記が当てはまる場合、常に同じ数になるため、末尾の等号を取り除くことができます。その場合は、デコードする前に、同じ数の等号を文字列に追加するだけです。

ダイジェストが固定長でない場合、等号をトリミングすることは安全ではありません。

編集:SHA-256ダイジェストを使用しているように見えますか? SHA-256ダイジェストは256ビット(または32バイト)です。 32バイトは3の10グループと残りの2つです。 パディングに関するウィキペディアのセクション ;からわかるようにつまり、末尾に等しいものが常に1つあるということです。 SHA-256の場合は、デコードする前に再度追加することを忘れない限り、削除しても問題ありません。

16
Martin Ellis

Base64としてエンコードする必要がある3バイトごとに4 ASCII文字に変換され、 '='文字が結果を埋めるために使用されるため、常に4つのエンコードされた文字の倍数が存在します。正確に3バイトの倍数である場合、等しい符号は得られません。1つのスペアバイトは、最後に2つの「=」文字を取得することを意味します。2つのスペアバイトは、最後に1つの「=」文字を取得することを意味します。デコード方法によって異なります。これを有効な文字列と見なす場合と見なさない場合があります。お持ちの文字列の例では、デコードされませんが、私が試したいくつかの単純な文字列はデコードされます。

このページを読んで、base64文字列とエンコード/デコードについて理解を深めることができます。

http://www.nczonline.net/blog/2009/12/08/computer-science-in-javascript-base64-encoding/

出力文字列をチェックするために使用できる無料のオンラインエンコーダー/デコーダーがあります

18
Brian

等号が何をするかを知っている限り、等号を削除しても問題ありません。

Base64は、エンコードする3バイトごとに4文字を出力します(つまり、各文字は6ビットをエンコードします)。埋め込み文字は、base64文字列の長さが常に4の倍数になるように追加されます。埋め込み文字は、実際にはデータをエンコードしません。 (私は確かに言うことはできませんなぜこれが行われた-文字列が切り捨てられたかどうかをエラーチェックする方法として、デコードを容易にするため、または他の何か?).

いずれにせよ、つまり、x base64文字(パディングなし)がある場合、4-(x%4)パディング文字があります。 (ただしx%4=1 6と8)の因数分解により、発生することはありません。これらには実際のデータが含まれておらず、復元できるため、スペースを節約したい場合は、これらを頻繁に削除します。以下::

from base64 import b64encode, b64decode

# encode data
raw = b'\x00\x01'
enc = b64encode(raw).rstrip("=")

# func to restore padding
def repad(data):
     return data + "=" * (-len(data)%4)
raw = b64decode(repad(enc))
11
Eli Collins

@Martin Ellisが指摘する場合を除いて、パディング文字をいじると、

TypeError: Incorrect padding

そして、あなたがそれにいる間にいくつかのゴミを生成します。

@MattHで述べられているように、base64はスペースを節約するのとは逆のことをします。

スペースを節約する代わりに、zlibなどの圧縮アルゴリズムを適用する必要があります。

たとえば、zlib

import zlib

s = '''large string....'''
compressed = zlib.compress(s)

compression_ratio = len(s)*1.0/len(compressed)    

# And later...
out = zlib.decompress(compressed) 

# The above function is also good for relieving stress.
1
HeyWatchThis

それらはパディングであり、最大で2つあるため、削除してもあまり節約できません。スペースを節約したい場合は、他の場所を探してください。エントロピーを参照して、これらのbase64文字列を圧縮していますか?その場合、それらを削除しても、圧縮サイズにはあまり影響しません。

1
Dan D.

そうは思いません。 http://en.wikipedia.org/wiki/Base64#Padding

これらの等しいものは「便利」です

0
oleg.chubin