Base64urlをDecodeする

はじめに

Amazon Cognitoを使った開発をしていてJWTできた文字列をbase64urlからbase64にデコードする必要があったので試してみました。

仕組みについて

Base64urlをデコードする前に、Base64urlにエンコードする際どう切り替わっているか理解している必要があります。
Base64urlエンコードでは”+”を”-“に、”/”を”_”、”=”を””に変換しています。

“-“と”_”の文字列を”+”と”/”に置き換えるのは簡単ですが、問題は””を”=”に変換する箇所です。

“=”は一体何を表しているのかですが、以下の引用のように”=”はデータがかけているのか判定を行うために空白を埋めるために使われている文字なので4文字ずつ区切って余が出た場合に追加すればよさそうです。

送られてきた文字列を4文字ずつで区切ってみたら最後が3文字だった、というときに転送したデータが欠けていたのか、残りをパディングで埋めて読み込んで良いのかわからない、ということですね。
パディングがあって4文字でピッタリ終わっていれば迷うことはないはずです。

https://teratail.com/questions/196952

コード

func base64URLDecode(_ encodedString: String) -> String {
    // jwtはbase64urlエンコードされた状態なのでbase64に戻すそのまま置き換えられる-と_を戻す
    let stringTobeEncoded = encodedString
        .replacingOccurrences(of: "-", with: "+")
        .replacingOccurrences(of: "_", with: "/")
    
    // 4で割り切れない分は=で穴埋め
    let remainder = encodedString.count % 4
    let paddingCount = remainder == 0 ? 0 : abs(remainder - 4)
    
    return stringTobeEncoded + String(repeating:"=", count:paddingCount)
}

参考

なぜBase64では=で文字埋めするのですか?