[解決済み] swiftでデータを16進文字列に変換する方法
質問
SwiftでDataの値を16進数で表示したいのですが。
最終的にはこんな風に使いたい。
let data = Data(base64Encoded: "aGVsbG8gd29ybGQ=")!
print(data.hexString)
どのように解決するのですか?
簡単な実装( SwiftでSHA1を使ってNSStringをハッシュする方法は? を参考にし、大文字出力のオプションを追加したもの) は次のようになります。
extension Data {
struct HexEncodingOptions: OptionSet {
let rawValue: Int
static let upperCase = HexEncodingOptions(rawValue: 1 << 0)
}
func hexEncodedString(options: HexEncodingOptions = []) -> String {
let format = options.contains(.upperCase) ? "%02hhX" : "%02hhx"
return self.map { String(format: format, $0) }.joined()
}
}
を選んだのは
hexEncodedString(options:)
メソッドを既存のメソッドのスタイルで
base64EncodedString(options:)
.
Data
に準拠し
Collection
プロトコルに準拠しているので
map()
を使って各バイトを対応する16進文字列に対応付けることができます。
そのため
%02x
形式は,引数を16進数で表示し,2桁まで埋める。
に,必要ならば先頭の0を加えて表示する。また
hh
修飾子を使うと,引数
(スタック上で整数として渡される)は1バイトの量として扱われる。
量として扱われます。ここで修飾子を省略することができるのは
$0
は
符号なし
の数である (
UInt8
) で、符号拡張は行われませんが、そのままでも問題ありません。
を残しておいても害はありません。
その結果、1つの文字列に結合されます。
例
let data = Data([0, 1, 127, 128, 255])
// For Swift < 4.2 use:
// let data = Data(bytes: [0, 1, 127, 128, 255])
print(data.hexEncodedString()) // 00017f80ff
print(data.hexEncodedString(options: .upperCase)) // 00017F80FF
以下の実装は、50倍ほど高速です。
(1000ランダムバイトでテスト)。この実装は
RenniePetの解決策
と
Nick Mooreの解答
を利用していますが
String(unsafeUninitializedCapacity:initializingUTF8With:)
は Swift 5.3/Xcode 12 で導入され、macOS 11 および iOS 14 以降で利用可能です。
このメソッドは、不要なコピーや再割り当てを行わずに、UTF-8ユニットからSwift文字列を効率的に作成することができます。
古い macOS/iOS バージョンのための代替実装も提供されています。
extension Data {
struct HexEncodingOptions: OptionSet {
let rawValue: Int
static let upperCase = HexEncodingOptions(rawValue: 1 << 0)
}
func hexEncodedString(options: HexEncodingOptions = []) -> String {
let hexDigits = options.contains(.upperCase) ? "0123456789ABCDEF" : "0123456789abcdef"
if #available(macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0, *) {
let utf8Digits = Array(hexDigits.utf8)
return String(unsafeUninitializedCapacity: 2 * self.count) { (ptr) -> Int in
var p = ptr.baseAddress!
for byte in self {
p[0] = utf8Digits[Int(byte / 16)]
p[1] = utf8Digits[Int(byte % 16)]
p += 2
}
return 2 * self.count
}
} else {
let utf16Digits = Array(hexDigits.utf16)
var chars: [unichar] = []
chars.reserveCapacity(2 * self.count)
for byte in self {
chars.append(utf16Digits[Int(byte / 16)])
chars.append(utf16Digits[Int(byte % 16)])
}
return String(utf16CodeUnits: chars, count: chars.count)
}
}
}
関連
-
[解決済み] Swiftで#pragmaマーク?
-
[解決済み] Swift Betaのパフォーマンス:配列のソート
-
[解決済み] 純粋な」Swift で弱いプロトコル参照を作るには (@objc なしで) どうしたらいいですか?
-
[解決済み] Swift: print() vs println() vs NSLog()
-
[解決済み] 2倍値を小数点以下x桁に丸める処理を素早く行う。
-
[解決済み] SwiftでURLから画像を読み込む/ダウンロードする
-
[解決済み] SwiftでStringのサブストリングはどのように動作するか
-
[解決済み] Swiftの配列を文字列に変換するには?
-
[解決済み] Swift での Int の先頭のゼロ
-
[解決済み] SwiftUIで条件付きでビューを使用する
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
Swift Error fatal error: Optional value のアンラップ中に予期せず nil を発見した。
-
[解決済み] UIViewの定高制約をプログラムで更新するには?
-
[解決済み] Swiftで警告を消すには?
-
[解決済み] ""内の二重引用符を印刷するには?
-
[解決済み] 固定サイズのオブジェクトの配列を作成する方法
-
[解決済み] Swiftの変数に"?"(クエスチョンマーク)と"!"(エクスクラメーションマーク)の装飾を施す。
-
[解決済み] ラウンドトリップスウィフト番号の種類は、データとの間で
-
[解決済み] Swift- Remove Push Notification Badge number?
-
[解決済み] Swiftでenumをプロトコルに準拠させるには?
-
[解決済み] XcodeでFirebase Analyticsをオンにする