Python の base64.py はマニュアルででかでかと RFC 3548 をうたっているのですが、全然準拠できてないことに気づきました。
RFC 3548 には
Implementations MUST reject the encoding if it contains characters outside the base alphabet when interpreting base encoded data, unless the specification referring to this document explicitly states otherwise. Such specifications may, as MIME does, instead state that characters outside the base encoding alphabet should simply be ignored when interpreting data ("be liberal in what you accept"). Note that this means that any CRLF constitute "non alphabet characters" and are ignored.
とあり、要するに「base alphabet でない文字が混ざってるエンコード文字列を解釈しようとしたら拒絶しろ (ただし仕様として明記すれば他の挙動でも可)」という感じ *1 。しかるに
$ ./python3.0 Python 3.0rc1 (r30rc1:66499, Sep 22 2008, 21:33:51) [GCC 4.3.2] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import base64 >>> base64.standard_b64decode(b'Y!"#$%&()-^~\\|[]@;:<>,.?_\nQ==') b'a'
思いっきり許容 (無視) してる。マニュアルにそれっぽい断りは書かれてないのに。
RFC 3548 中の MUST はたった 3 つなのに守れてない base64.py に失望した!それをチェックせずに添付してる Python に失望した!
いい加減な子がミスしても評価は変わらないけど、しっかりした子だと思われてる子がミスすると一気に評価が下がるのです。
ちなみに他の言語の状況は。
- ruby は 「Base64は、(略) RFC 2045で定義されています。」なので問題ない。(RFC 2045 は改行無視でも可 (のはず))
- perl も the base64 encoding specified in RFC 2045 なので問題ない。
- php は 説明中で RFC を明記していないので問題ない。(See Also には RFC 2045 が書かれている)
- gauche は The characters which does not in legal Base64 encoded character set are silently ignored.と明記しているので問題ない。
*1:万が一ぼくの解釈が間違ってたらやさしく教えてね!