Base32 より Base64 のほうが効率的って聞きました!
from base64 import b32decode, b64decode
b32 = input("Base32: ")
b64 = input("Base64: ")
assert b32.count("=") == 0 and b64.count("=") == 0, "Don't use padding!"
assert b32decode(b32) == b64decode(b64), "Decoded values are not equal!"
# Base32: 5 bits -> 1 char,
# Base64: 6 bits -> 1 char, so ...
if len(b32) >= len(b64):
print("Expected :)")
else:
# never reach here :)
print("Wow... The flag is Alpaca{**** REDACTED ****}")
このコードでフラグが出るのは**len(b32) < len(b64)**のときだけです。
しかし同じバイト列を表す場合、通常はBase32(5bit/文字)のほうが Base64(6bit/文字)より長くなるため上手くいかなそうです。
ここで Python の base64 モジュールの挙動差を利用します。
b64decode はデフォルト(validate=False)だと Base64アルファベット外の文字を無視します。
そのため、デコード結果を変えずに文字数だけ増やせます。←これを使います。
なお、b32decode は 非アルファベット文字があるとエラーになります。
そのため、Base32 側は同様の水増しができません。
また、1byte=8bit、Base32は5bit単位、Base64は6bit単位なので、
8・5・6 の最小公倍数 120bit = 15byteにすれば以下の条件も通ります。
assert b32.count("=") == 0 and b64.count("=") == 0, "Don't use padding!"
が、15byte用意しなくても空文字(0byte)になるようにすれば通ります。
echo -e "\\n."|nc 34.170.146.252 60350
Base32: Base64: Wow... The flag is Alpaca{BASE32ISSUPERIOR}