SwiftでSHA256ハッシュ+Base64+URLセーフエンコードを行うには

サーバ屋さんが MQTT ClientID SHA256ハッシュにくわえ、Base64+URLセーフエンコード にしてくれと言われるので調べて対応した覚え書きです。単にユニーク値で記号を含まないなら、SHA256だけでもいいと思うのですが... こだわりか既存のサーバの作込みがそうなってるのかなと...

Swiftでも、SHA256ハッシュ、Base64 のAPIはありましたが、URLセーフエンコードはなく、これはロジックで組む必要がありました。またこの3段階変換を行い、デバッグ用に中間変換結果も確認しするには、少々オブジェクトの選択扱いがややこしいようでした。コードは以下のとおりです。

  public func ConvertKey(
		baesKey: String, 	// 変換対象のキー
	) -> String
    {
        var ret: String = ""
        
        //--- SHA256値をBase64にエンコードし、URL safeにする。---
        let srcBin:Data?    = baesKey.data(using: .utf8)    // Binaly変換 
        let hashVal         = SHA256.hash( data: srcBin! )  // SHA256ハッシュ (内部はByte配列)
        let hashBin:Data?   = Data( hashVal )               // Binaly変換
        
        // 生成結果のDBG用の確認トレース
        let hastStr = hashVal.compactMap { String(format: "%02x", $0) }.joined()
        print( "HASH=" + hastStr + " len=" + String(hastStr.count) )
        
        // URL64エンコード 
        if let stg1 = hashBin?.base64EncodedString() {
            // Memo: Swiftには、URLセーフAPIはないため、ハンドコードで変換する。
            let stg2    = stg1.replacingOccurrences(of: "=", with: "" )
            let stg3    = stg2.replacingOccurrences(of: "+", with: "-")
            ret         = stg3.replacingOccurrences(of: "/", with: "_")
        }
        else {
            print( "base64EncodedString() error.")
        }
        
        return ret
 }

一旦、Binaly値に変換してあげるとスマートに収まりました。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です