文字列を16進数で確認したい時に使う。
動作確認環境
Ruby 2.7.1
UTF-8
16進数への変換
String#unpack
や String#bytes
を利用できる。
unpack
UTF-8のコードポイントを調べる方法
引数に ("U*")
を指定し、得られた数字を to_s(16)
で16進数に変換している
"𩸽".unpack("U*").map { |s| "U+#{s.to_s(16).upcase}" }
=> ["U+29E3D"]
"あいうえお".unpack("U*").map { |s| "U+#{s.to_s(16).upcase}" }
=> ["U+3042", "U+3044", "U+3046", "U+3048", "U+304A"]
または引数に("H*")
を指定することで、16進数の値が返される。
text = "1"
text.unpack("H*")
# => ["31"]
文字列をまとめて unpack
すると読みづらい。
text = "123αβγあいう🌀"
text.unpack("H*")
# => ["313233ceb1ceb2ceb3e38182e38184e38186f09f8c80"]
この場合、1文字ずつ unpack
すると読みやすい。
text = "123αβγあいう🌀"
text.chars.map { |t| t.unpack("H*") }
# => [["31"], ["32"], ["33"], ["ceb1"], ["ceb2"], ["ceb3"], ["e38182"], ["e38184"], ["e38186"], ["f09f8c80"]]
bytes
文字列の各バイトが数値の配列で返される。
bytes
を使うと10進数で表示される1ので、16進数に変換する。
text = "吾輩は猫である。"
text.bytes
# => [229, 144, 190, 232, 188, 169, 227, 129, 175, 231, 140, 171, 227, 129, 167, 227, 129, 130, 227, 130, 139, 227, 128, 130]
text.bytes.map { |b| "%02X" % b }
# => ["E5", "90", "BE", "E8", "BC", "A9", "E3", "81", "AF", "E7", "8C", "AB", "E3", "81", "A7", "E3", "81", "82", "E3", "82", "8B", "E3", "80", "82"]
# こうも書ける
text.bytes.map { |b| b.to_s(16) }
# => ["e5", "90", "be", "e8", "bc", "a9", "e3", "81", "af", "e7", "8c", "ab", "e3", "81", "a7", "e3", "81", "82", "e3", "82", "8b", "e3", "80", "82"]
UTF-8の文字コード表と照らし合わせれば何の文字が入っているか分かる。
UTF-8の文字コード表 - 備忘帳 - オレンジ工房
-
bytes
は10進数に変換しているわけではない。返り値のInteger オブジェクトを表示するときに、10進法に基づく文字列化を行っている。 ↩