サーバ屋さんが 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値に変換してあげるとスマートに収まりました。