【Python】16進数の使い方を初心者向けにわかりやすく解説

はじめに

Pythonで数値を扱うとき、16進数という表現方法が便利に感じることはないでしょうか。
「10進数」や「2進数」に比べると、16進数はあまり使ったことがないという方もいるかもしれません。

しかし、ネットワーク通信やハードウェア制御、暗号化などのシステム開発では、16進数の表現が必要になる場面が出てきます。
たとえば、データをコンパクトに書き表すとき、あるいは特定の設定ファイルで値を指定するときなど、初心者でも遭遇しやすいシーンがあります。

今回は、Pythonで16進数を扱う基本的な方法をまとめます。
ここで紹介する内容を押さえると、10進数から16進数への変換はもちろん、16進数から10進数への変換もしやすくなりますので、実務で扱う場面にスムーズに対応できるでしょう。

この記事を読むとわかること

  • Pythonにおける16進数の基本的な表記方法
  • 10進数から16進数へ変換する方法と、その逆の変換方法
  • hex() 関数や format() を使った実装方法
  • 実務で16進数を使う具体的なシーンや注意点

Pythonで16進数を扱うメリット

Pythonで16進数を扱うメリットは主に2つあります。
1つ目は、数値データを見やすく表現できるという点です。
10進数に比べて表示が短くなるので、通信ログを解析するときや暗号関連のデータを扱うときなどに役立ちます。

2つ目は、システム開発に必要な場面が多いことです。
たとえば、ネットワークやハードウェアとやり取りする場合に、16進数で指定するプロトコルやフォーマットが存在します。
特定の値を指定するときに16進数で書くというケースもあるため、Pythonのコード中で扱えるようになっていると実務での幅が広がります。

16進数の基本表記

Pythonでは、16進数リテラルを表すときに、先頭に 0x を付けて数値を書きます。
たとえば 0x1F0xA0 のように記述することで、これは「16進数です」という宣言になります。

もし 0x をつけないで単に 1F と書いてしまうと、Pythonの文法的にはエラーになるので注意してください。
16進数であることを明示するために、必ず 0x をつけるという約束があるのです。

10進数から16進数への変換

hex() 関数を使った変換

もっともシンプルな方法は、組み込み関数である hex() を使うやり方です。
10進数の整数を hex() に渡すと、16進数の文字列表現が返ってきます。

number = 31
hex_value = hex(number)
print(hex_value)  # 0x1f

上記の例では number31 を入れ、 hex() 関数で 0x1f という文字列が得られます。
返される文字列には先頭に 0x が付くことを覚えておきましょう。

format() を使った変換

format() 関数やフォーマット文字列を使えば、少し柔軟な形で16進数に変換できます。

number = 31
hex_str_lower = format(number, "x")  # "1f"
hex_str_upper = format(number, "X")  # "1F"

print(hex_str_lower)  # 1f
print(hex_str_upper)  # 1F

ここでは、第二引数に "x" を指定すると小文字の16進数表現、"X" を指定すると大文字の16進数表現が得られます。
0x はつかないので、必要に応じて文字列を連結すると良いでしょう。

f-stringでの変換

Pythonのf-stringを使っても16進数を簡単に出力できます。

number = 31
print(f"{number:x}")  # 1f
print(f"{number:X}")  # 1F

この場合も、出力される文字列に 0x は含まれません。
ただし、小文字か大文字かは指定したフォーマット文字に依存します。

16進数を10進数に変換

16進数を表す文字列を受け取って、それを10進数の整数に変換することもよくあります。
その際には、組み込み関数の int() を使います。

hex_str = "1f"
decimal_value = int(hex_str, 16)
print(decimal_value)  # 31

上記では "1f" という16進数文字列を、int() 関数で基数を 16 に指定することで 31(10進数)に変換しています。
また 0x1f のように 0x が先頭についている文字列に対しては、その文字列をスライスした上で同様の方法で変換すると良いでしょう。

0x の表記を活用するシーン

コードの中で 0x が付いた値を直接扱うシーンはそれほど多くないかもしれません。
しかし、たとえばネットワーク通信の際に特定のポート番号を16進数で書いて管理する場合や、バイナリデータを扱う際にアドレスを16進数で指定するというケースもあります。

通信ログや特殊な設定ファイルで16進数が使われていて、開発時に読みやすい形で表示したいときは、まず hex()format() で文字列を取得してみましょう。
その後、表記の工夫をするなどして情報整理するとスムーズです。

実務での活用例

実務では、16進数を活用する場面がいくつか考えられます。
ここでは3つの例を紹介します。

ログ解析

サーバー上で動作するプログラムが出力するログには、ネットワーク上でのやり取りが16進数のまま記録されることがあります。
特にパケットのヘッダ情報や制御コードなどを読み解くとき、Pythonで変換して10進数の値を参照しつつ調べる方法は実践的です。

暗号関連のデータ

暗号化された文字列やハッシュ値などは16進数で表記されるケースが多いです。
Pythonを使ってハッシュ値をチェックしたり署名を扱ったりするときは、16進数を文字列で取り扱うことが一般的と言えるでしょう。

ネットワークプログラミング

IPv6アドレスやMACアドレスなどは16進数の表記と密接に関わります。
たとえばMACアドレスをプログラムで扱う際は、各バイトを16進数で連結した書き方になるため、Pythonでのパースや生成が必要になることがあります。

16進数を扱うときの注意点

16進数を扱う場合、文字列と数値の区別を明確にすることが大切です。
ログ解析や設定ファイルの読み込みなどを行う際には、最初は文字列として受け取り、整数として扱う段階で int(hex_str, 16) のように変換します。

また、Pythonのビット演算を使って特定のフラグをチェックするような処理も、16進数の値と相性がいいです。
ただし、16進数だからといって特別な優先順位があるわけではなく、あくまでデータは数値という点は変わりません。
0x表記にするかどうかは可読性や運用ルールによるので、チーム内で話し合って決めるとよいでしょう。

具体例:2進数・16進数を混在で扱う

16進数と2進数を行き来する例を少し見てみましょう。
たとえば、ある16進数を2進数に変換したい場合、10進数に一度変換し、それから2進数へ変換することが多いです。

hex_str = "7F"       # 16進数
decimal_val = int(hex_str, 16)
binary_str = format(decimal_val, "b")  # 2進数
print(binary_str)  # 1111111

このように、途中で10進数を介すのが基本です。
直接16進数の文字列を2進数に変換する仕組みはありませんが、少し手順を増やすだけで簡単に実装できます。

Pythonで数値を扱ううえでのポイント

Pythonでは、数値リテラルに関して複数の記法が用意されています。
このことは、2進数や8進数、16進数などをわかりやすく扱うための一助となっています。

  • 2進数:0b を付ける (例: 0b1010)
  • 8進数:0o を付ける (例: 0o12)
  • 16進数:0x を付ける (例: 0x1f)

また、アンダースコア _ を用いた区切りもできます。
たとえば 0x1f_ff のように書くと、0x1fff と同じ値となり、可読性が上がるかもしれません。

予期せぬ変換ミスへの対処

16進数を扱うとき、もしコードでエラーや想定外の出力が出るとしたら、その原因の多くは基数の指定ミス文字列形式の扱いミスにあることが多いです。

int("1g", 16) のように、16進数では使えない文字を入れてしまうとエラーが発生します。
また、0x を含む文字列をそのまま int() に渡してエラーになった場合も、先に 0x を取り除くか、最初から 0x を付けない文字列に直して処理する必要があります。

16進数の変換でエラーが出た場合、多くは文字列のフォーマットが原因です。余計な接頭辞やアルファベットの大小をチェックしてみましょう。

実務で意識しておきたいこと

実務の現場で16進数を扱う際は、コード中で直接 0x を使うよりも、可読性を優先する工夫をする場合があります。
たとえば、16進数の表現を数値として定義するのではなく、設定ファイルや定数ファイルにまとめることでわかりやすくなるかもしれません。

また、暗号化された文字列などは桁数が多いことが通常です。
このような長い16進数を手作業で確認するとミスが起きやすいので、Pythonのコードで自動的に桁数を数えたり、グルーピングしたりすると便利です。

Pythonにおけるエラーハンドリングの例

16進数をパースするときは、エラー時に落ちてしまわないように例外処理を仕込むと安心です。
以下のように、エラー時に対処できるようにすると、予期せぬ文字列が来ても安全に処理できます。

def hex_to_decimal(hex_str):
    try:
        return int(hex_str, 16)
    except ValueError:
        return None  # 不正な文字列の場合はNoneを返す

value = hex_to_decimal("zzz")
if value is None:
    print("不正な16進数文字列です")
else:
    print(value)

このような例外処理を入れておくと、ログ解析などで実行途中にスクリプトが止まってしまうリスクを減らせます。

まとめ

Pythonで16進数を扱う際には、hex(), format(), f-string など便利な方法が複数用意されています。
実務で登場するデータも、16進数の形式でやりとりされる場合があるため、10進数との変換方法やエラーハンドリングを知っておくと開発がスムーズに進むでしょう。

16進数の取扱いは、それほど難しくありません。
数値をリテラルで書く場合は 0x を使い、文字列を数値に変換する場合は int(str_value, 16) を使うという基本を押さえておけば、初歩的な場面はクリアできます。
あとは可読性や保守性の観点で、必要に応じてフォーマット文字列や関数を使い分けるとよいでしょう。

Pythonをマスターしよう

この記事で学んだPythonの知識をさらに伸ばしませんか?
Udemyには、現場ですぐ使えるスキルを身につけられる実践的な講座が揃っています。