文字列を16進バイトとして出力しますか?


155

私はこの文字列を持っています:Hello world !!そして、Python asを使用してそれを印刷したいです48:65:6c:6c:6f:20:77:6f:72:6c:64:20:21:21

hex() 整数に対してのみ機能します。

どうすればできますか?


アイデアが2桁の16進数値のみを返すことである場合、この質問はバイト文字列(つまり、Python 2 strまたはPython 3 bytestring)の使用を意味します。0〜255の整数への文字の明確な変換はないためです。したがって、文字列(Python 2 unicodeおよびPython 3 str)は、この16進形式に変換する前に、まずエンコードを必要とします。アーロン・ホールの答えはこれを例証しています。
Eric O Lebigot

回答:


227

文字列をintジェネレーターに変換し、各要素に16進フォーマットを適用して、セパレーターを挿入できます。

>>> s = "Hello world !!"
>>> ":".join("{:02x}".format(ord(c)) for c in s)
'48:65:6c:6c:6f:20:77:6f:72:6c:64:20:21:21

3
python3では、str16進数としてa を出力するという概念は実際には意味をなさないことに注意してください。bytesオブジェクトを16進数として印刷する必要があります(strbytes呼び出してに変換します.encode())。
mic_e

8
実際には、これはのpython3に無効な出力を生成する:":".join("{:02x}".format(ord(c)) for c in 'løl')戻り'6c:f8:6c'、一方では、":".join("{:02x}".format(c) for c in 'løl'.encode())正しいUTF-8表現を生成します'6c:c3:b8:6c'
mic_e

2
この質問と回答は、入力に非ASCII文字が含まれないことを前提としています。あなたの入力は絵文字や非ラテンベースの管理能力のシステムのようなものが含まれている可能性がある場合は、使用する場合があります":".join("{:04x}".format(ord(c)) for c in s)(交換する02x04x代わりに4桁の数字であることをゼロパッドにそれぞれ番号を)
ボリス

@mic_eなんでこれ?Scapyは、組み込みインタープリターでこれを試すときにこれを参照します。WARNING: Calling str(pkt) on Python 3 makes no sense!
sherrellbc

157
':'.join(x.encode('hex') for x in 'Hello World!')

3
python3でこれを行う方法?
h__ 2013

6
@hyh:2桁ごとの16進数の後h = binascii.hexlify(b"Hello world !!") to get hex string. b":".join(h[i:i+2] for i in range(0, len(h), 2))に挿入':'します。
jfs 2014年

2
Python 3では動作しませんLookupError: 'hex' is not a text encoding; use codecs.encode() to handle arbitrary codecs
Boris

55

Python 2.xの場合:

':'.join(x.encode('hex') for x in 'Hello World!')

上記のコードはPython 3.xでは機能しません。3.xの場合、以下のコードは機能します。

':'.join(hex(ord(x))[2:] for x in 'Hello World!')

1
また、
後者

1
ただし、後者は先行ゼロを埋めないことに注意してください。hex(ord( "\ x00"))[2:]は "0"であり、 "\ x00" .encode( "hex")== "00"
Will Daniels

3
これらのソリューションの両方が他のユーザーから提供されてから数か月後、なぜこれを新しい回答として投稿することにしたのですか?バージョンの互換性を明確にすることがポイントである場合、既存の回答の編集を提案する方が理にかなっています。
Air

2
他の場所で述べたように、いったんASCIIを超えてUnicodeを検討すると、この答えは正しくありません。':'。join(hex(ord(x))[2:] for x in 'løl')は '6c:f8:6c'を誤って出力しますが、正しい出力は '6c:c3:b8:6c'です。
mcduffee

23

読みやすいと思われる2行の別の回答で、文字列内の改行やその他の奇妙な文字のデバッグに役立ちます。

Python 2.7の場合

for character in string:
    print character, character.encode('hex')

Python 3.7(3のすべてのリリースではテストされていません)

for character in string:
    print(character, character.encode('utf-8').hex())

これはPython 3.6.8(少なくとも)では機能しません。「hex」は文字列のエンコーディングではありません。codecs.encode(<bytestring>, "hex")ただし、機能します。
Eric O Lebigot

2
ああ、情報に感謝します...ええ、これは間違いなくPython 2.7用に書かれました。回答を更新して、Python 3.7でそれを行う方法を含めます。
copeland3300

確認済み、Pythonの3.7.6:import sys; s="Déjà vu Besançon,Lupiñén,Šiauliai,Großräschen,Łódź,Аша,广东省,LA"; for c in s:; w=sys.stdout.write(c+":"+c.encode('utf-8').hex()+"||"); (out)D:44||é:c3a9||j:6a||à:c3a0|| :20||v:76||u:75|| :20||B:42||e:65||s:73||a:61||n:6e||ç:c3a7||o:6f||n:6e||,:2c||L:4c||u:75||p:70||i:69||ñ:c3b1||é:c3a9||n:6e||,:2c||Š:c5a0||i:69||a:61||u:75||l:6c||i:69||a:61||i:69||,:2c||G:47||r:72||o:6f||ß:c39f||r:72||ä:c3a4||s:73||c:63||h:68||e:65||n:6e||,:2c||Ł:c581||ó:c3b3||d:64||ź:c5ba||,:2c||А:d090||ш:d188||а:d0b0||,:2c||广:e5b9bf||东:e4b89c||省:e79c81||,:2c||L:4c||A:41||
bballdave025

20

ヒョードルゴゴレフの回答を補完するもの:

まず、文字列に「ASCIIコード」が10未満の文字が含まれている場合、それらは必要に応じて表示されません。その場合、正しい形式は次のようになります{:02x}

>>> s = "Hello unicode \u0005 !!"
>>> ":".join("{0:x}".format(ord(c)) for c in s)
'48:65:6c:6c:6f:20:75:6e:69:63:6f:64:65:20:5:20:21:21'
                                           ^

>>> ":".join("{:02x}".format(ord(c)) for c in s)
'48:65:6c:6c:6f:20:75:6e:69:63:6f:64:65:20:05:20:21:21'
                                           ^^

次に、「文字列」が実際に「バイト文字列」である場合、そしてPython 3では違いが重要であるため、次のようにすることができます。

>>> s = b"Hello bytes \x05 !!"
>>> ":".join("{:02x}".format(c) for c in s)
'48:65:6c:6c:6f:20:62:79:74:65:73:20:05:20:21:21'

上記のコードでは、バイトオブジェクトは「0 <= x <256の範囲の整数の不変のシーケンス」として定義されているため、変換する必要はありません。


11

文字列を16進バイトとして出力しますか?

受け入れられた答えは与える:

s = "Hello world !!"
":".join("{:02x}".format(ord(c)) for c in s)

戻り値:

'48:65:6c:6c:6f:20:77:6f:72:6c:64:20:21:21'

受け入れられた回答は、バイト(主にASCII文字)を使用している場合にのみ機能します。しかし、ユニコードを使用する場合、例えば:

a_string = u"Привет мир!!" # "Prevyet mir", or "Hello World" in Russian.

どういうわけかバイトに変換する必要があります。

端末がこれらの文字を受け入れない場合は、UTF-8からデコードするか、名前を使用できます(そのため、コードを貼り付けて一緒に実行できます)。

a_string = (
    "\N{CYRILLIC CAPITAL LETTER PE}"
    "\N{CYRILLIC SMALL LETTER ER}"
    "\N{CYRILLIC SMALL LETTER I}"
    "\N{CYRILLIC SMALL LETTER VE}"
    "\N{CYRILLIC SMALL LETTER IE}"
    "\N{CYRILLIC SMALL LETTER TE}"
    "\N{SPACE}"
    "\N{CYRILLIC SMALL LETTER EM}"
    "\N{CYRILLIC SMALL LETTER I}"
    "\N{CYRILLIC SMALL LETTER ER}"
    "\N{EXCLAMATION MARK}"
    "\N{EXCLAMATION MARK}"
)

だから私たちはそれを見る:

":".join("{:02x}".format(ord(c)) for c in a_string)

戻り値

'41f:440:438:432:435:442:20:43c:438:440:21:21'

不十分/予期しない結果-これらは、世界中の言語を表す、UnicodeコンソーシアムのUnicodeで見られる書記素を作成するために組み合わせるコードポイントです。ただし、これは実際にこの情報を格納する方法ではないため、他のソースによって解釈される可能性があります。

別のソースがこのデータを使用できるようにするには、通常、UTF-8エンコーディングに変換する必要があります。たとえば、この文字列をバイト単位でディスクに保存したり、htmlにパブリッシュしたりする必要があります。したがって、コードポイントをUTF-8のコード単位に変換するためのエンコーディングがord必要ですbytes。Python3では、整数の反復可能であるため、このエンコーディングは必要ありません。

>>> ":".join("{:02x}".format(c) for c in a_string.encode('utf-8'))
'd0:9f:d1:80:d0:b8:d0:b2:d0:b5:d1:82:20:d0:bc:d0:b8:d1:80:21:21'

または、おそらくよりエレガントに、新しいf文字列を使用します(Python 3でのみ利用可能):

>>> ":".join(f'{c:02x}' for c in a_string.encode('utf-8'))
'd0:9f:d1:80:d0:b8:d0:b2:d0:b5:d1:82:20:d0:bc:d0:b8:d1:80:21:21'

Pythonの2では、合格cord最初、すなわちord(c)-より多くの例:

>>> ":".join("{:02x}".format(ord(c)) for c in a_string.encode('utf-8'))
'd0:9f:d1:80:d0:b8:d0:b2:d0:b5:d1:82:20:d0:bc:d0:b8:d1:80:21:21'
>>> ":".join(format(ord(c), '02x') for c in a_string.encode('utf-8'))
'd0:9f:d1:80:d0:b8:d0:b2:d0:b5:d1:82:20:d0:bc:d0:b8:d1:80:21:21'

1
@ not2qubitもう一度これらの例を試してください-私はPython 2と3の違いに対処するために少し時間をかけました、そしてどうやら私はもともとPython 2のためにこれらを書いただけです。そして、QAに私の回答をありがとう!
アーロンホール

はい、それで終わりました。ありがとうございました!
not2qubit 2018年

8

あなたは使用することができるhexdumpのを

import hexdump
hexdump.dump("Hello World", sep=":")

.lower()小文字が必要な場合は追加してください)。これはPython 2と3の両方で機能します。


また、私が遭遇した問題です。hexdumpまたはその他のパッケージのインストールに問題がある場合は、通常、プロキシ設定が原因で、プロキシオプションを指定してpipを実行してみてください pip install -U hexdump --proxy http://proxy.address:port
Eduard Florinescu

実際、私はsudowith を使用するという間違いを犯しpipましたpacman。これはめちゃくちゃになりました...
Tobias Kienzler

6

map関数とlambda関数を使用すると、16進値のリストを生成できます。これは、印刷(または他の目的で使用)できます。

>>> s = 'Hello 1 2 3 \x01\x02\x03 :)'

>>> map(lambda c: hex(ord(c)), s)
['0x48', '0x65', '0x6c', '0x6c', '0x6f', '0x20', '0x31', '0x20', '0x32', '0x20', '0x33', '0x20', '0x1', '0x2', '0x3', '0x20', '0x3a', '0x29']

[hex(ord(c)) for c in s]
ボリス

2

これは次の方法で実行できます。

from __future__ import print_function
str = "Hello World !!"
for char in str:
    mm = int(char.encode('hex'), 16)
    print(hex(mm), sep=':', end=' ' )

これの出力は、次のように16進数になります。

0x48 0x65 0x6c 0x6c 0x6f 0x20 0x57 0x6f 0x72 0x6c 0x64 0x20 0x21 0x21



将来の参考のために、__future__は最近のバージョンのPython 2で利用可能な標準ライブラリであり、通常はPython 3でのみ下位互換性のある機能を作成するために使用できます。この回答print(text)では、print textPython 2 の構文を置き換える「印刷機能」機能を取得するために使用されます。Pythonのドキュメントをご覧ください。
エリックリード

2

Python3やコロンを気にしない人のためのもう少し一般的な:

from codecs import encode

data = open('/dev/urandom', 'rb').read(20)
print(encode(data, 'hex'))      # data

print(encode(b"hello", 'hex'))  # string

0

使用base64.b16encodepython2(そのビルトイン)

>>> s = 'Hello world !!'
>>> h = base64.b16encode(s)
>>> ':'.join([h[i:i+2] for i in xrange(0, len(h), 2)]
'48:65:6C:6C:6F:20:77:6F:72:6C:64:20:21:21'

これは機能しません。インポートに何を使用し、なぜ使用しないの.decode()ですか?
not2qubit 2018年

0

便宜上、非常にシンプルです。

def hexlify_byteString(byteString, delim="%"):
    ''' very simple way to hexlify a bytestring using delimiters '''
    retval = ""
    for intval in byteString:
        retval += ( '0123456789ABCDEF'[int(intval / 16)])
        retval += ( '0123456789ABCDEF'[int(intval % 16)])
        retval += delim
    return( retval[:-1])

hexlify_byteString(b'Hello World!', ":")
# Out[439]: '48:65:6C:6C:6F:20:57:6F:72:6C:64:21'

0

よりも高いパフォーマンスを提供するものについては''.format()、これを使用できます:

>>> ':'.join( '%02x'%(v if type(v) is int else ord(v)) for v in 'Hello World !!' )
'48:65:6C:6C:6F:20:77:6F:72:6C:64:20:21:21'
>>> 
>>> ':'.join( '%02x'%(v if type(v) is int else ord(v)) for v in b'Hello World !!' )
'48:65:6C:6C:6F:20:77:6F:72:6C:64:20:21:21'
>>> 

申し訳ありませんが、これで見栄えがよくなっただけでは見栄えが良く
なりません'%02x'%vが、それだけではint
がかかりb''ますord(v)

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.