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

生田 陸人
LuaGate エンジニア / 現役エンジニア
編集 LuaGate編集部

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

このレッスンで分かること

  • プログラムを書いていると 16 進数 (hexadecimal、略して hex) が頻繁に出てきます
  • なぜわざわざ 16 進数を使うのでしょうか
  • 16 進数は 0-9 に加えて A-F (または a-f) を桁として使います

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

16 進数 (hexadecimal) の文字列を 10 進数の整数に変換する関数を実装し、4 ビット = 1 桁の関係を理解する。

プログラムを書いていると 16 進数 (hexadecimal、略して hex) が頻繁に出てきます。CSS のカラーコード #FF6600、メモリアドレス 0x7FFE0000、エンコーディングの \xFF、ハッシュ値の a3f5... など、技術文書には 16 進数があふれています。

なぜわざわざ 16 進数を使うのでしょうか。それは 4 ビット = 1 という美しい対応があるからです。1 バイト (8 ビット) はちょうど 2 桁の 16 進数で表せて、視認性が抜群です。

16 進数は「4 ビットをまとめて 1 文字にする」記法。2 進数の桁数(文字数)を 1/4 に短縮できる。

16 進数の桁

16 進数は 0-9 に加えて A-F (または a-f) を桁として使います。

hexdecbinary
000000
110001
991001
A101010
F151111

たとえば "FF" は 10 進数で 15 * 16 + 15 = 255 であり、これは 1 バイトで表せる最大値です。"FF6600" のような CSS カラーコードは、上から R = FF = 255G = 66 = 102B = 00 = 0 の RGB 値が並んでいる、と読み解けます。

CSS の #FF6600R = 255G = 102B = 0。ビビッドなオレンジ色になる。

変換アルゴリズム

16 進数を 10 進数にするには、2 進数の場合と同じく 桁の重み付き和 を計算します。重みは 16^016^116^2 …。

例: "1A3" を 10 進数にする。

  • 1 * 16^2 = 256
  • A * 16^1 = 10 * 16 = 160
  • 3 * 16^0 = 3
  • 合計: 256 + 160 + 3 = 419

アルゴリズムとしては、左から 1 文字ずつ読みながら result = result * 16 + 桁の値 を繰り返します (ホーナー法)。桁の値0-9A-F を見て対応する整数に変換します。

diagram (will load when visible)

Python での実装

Python

def hexToDec(hex_str): result = 0 for ch in hex_str.upper(): if '0' <= ch <= '9': digit = ord(ch) - ord('0') elif 'A' <= ch <= 'F': digit = ord(ch) - ord('A') + 10 else: continue result = result * 16 + digit return result

ポイントを 3 つ整理します。

  • hex_str.upper() で大文字小文字を統一しておくと処理が楽
  • 0-9ord(ch) - ord('0') で数値に変換
  • A-Ford(ch) - ord('A') + 1010-15 に変換

JavaScript での実装

JavaScript

function hexToDec(hexStr) { let result = 0; for (const ch of hexStr.toUpperCase()) { let digit; if (ch >= '0' && ch <= '9') { digit = ch.charCodeAt(0) - '0'.charCodeAt(0); } else if (ch >= 'A' && ch <= 'F') { digit = ch.charCodeAt(0) - 'A'.charCodeAt(0) + 10; } else { continue; } result = result * 16 + digit; } return result; }

charCodeAt(0) で文字コードを取り出して引き算します。Python の ord() と同じ役割です。

2 進数との橋渡し

16 進数の本当のうま味は、2 進数との変換が暗算でできる こと。F = 1111A = 1010 のように 4 ビット単位で覚えればよく、0xFF6600 は瞬時に 11111111_01100110_00000000 と読めます。逆方向も同様で、10110010 なら 1011 0010 = B2 です。CPU のレジスタやメモリダンプを読むとき、この感覚は強力な武器になります。

プログラマがプロを名乗るには 0xA = 10100xF = 1111 くらいは暗算できると良い。

よくある間違い

1 つ目は 大文字小文字の混在 を考慮し忘れること。"ff""FF""Ff" も同じ 255 ですから、必ず upper()lower() で統一しましょう。2 つ目は 0x プレフィックス の扱いです。"0x1A3" のように先頭に 0x が付くケースがあります。本問題では付かない前提ですが、実務では startswith("0x") を見て切り落とす処理が必要です。3 つ目は chrord の混同です。ord('A')65 を返しますが、chr(65)'A' を返します (逆向き)。

やってみよう

  • hexToDec("FF")255 になる。
  • hexToDec("100")256 になる。
  • hexToDec("DEADBEEF")3735928559 になる。これは伝統的にメモリ未初期化のマーカーとして使われる値。
  • hexToDec("CAFEBABE")3405691582。これは Java の .class ファイルの先頭 4 バイトのマジックナンバー。
  • hexToDec("FACEFEED") hexToDec("BEEFDEAD") なども有名な hex 文字列。試して結果を見てみよう。

16 進数を扱えるようになると、メモリダンプ、ネットワークパケット、暗号、ファイルフォーマットの世界が一気に身近になります。

よくある質問

Q. 進数変換はなぜプログラミングで必要なのですか?

A. コンピュータは内部で 2 進数を扱うため、ビット演算やメモリ操作で 2 進・16 進の理解が必須です。色コード(#FF8800)、ファイル権限(0755)、IP アドレスのサブネット計算など、実務でも進数変換に触れる機会は多くあります。

Q. 10 進数を 2 進数に変換するアルゴリズムは?

A. 数を 2 で割り続け、余りを下から並べると 2 進表現になります。例えば 13 → 6 余 1 → 3 余 0 → 1 余 1 → 0 余 1 で 1101 です。多くの言語は bin() / Integer.toBinaryString() などの組み込みがあるため、それを使うのが安全です。

Q. Base64 はなぜ 4/3 倍に膨らむのですか?

A. 3 バイト(24 ビット)を 4 文字(各 6 ビット)に変換するため、データ量が 4/3 倍になります。8 ビット境界の任意バイト列を ASCII 印字可能文字だけで安全に運ぶための仕組みで、メール添付や URL 内のバイナリ埋め込みで使われます。

次のレッスン

次は 第 1 章まとめクイズ に進みましょう。

事前確認 — 進む前に次の 3 つができることを確認しましょう。

  1. 16 進数変換 の要点を自分の言葉で説明できる
  2. このレッスンの最小コード (または操作手順) を見ずに書ける
  3. 練習問題やクイズで間違えた箇所を読み直して理解した

理解度チェック (30 秒)

Q. 16 進数変換 とは何か、1 文で説明してください。

この章のポイント

A. 本文の「このレッスンで分かること」または冒頭の説明文を見直し、自分の言葉で要約できれば OK。詰まったら本レッスンの最初の H2 セクションを読み返してみましょう。

関連レッスン

要件

  1. 0-9、A-F、a-f のみからなる文字列と仮定して良い (0x プレフィックスはない)
  2. 組み込みの基数変換 (int(s, 16) / parseInt(s, 16) / Integer.parseInt(s, 16)) は使わない
  3. 大文字小文字どちらも処理できること

入出力例

test-cases.txt

hexToDec("FF")255 hexToDec("0")0 hexToDec("1A3")419 hexToDec("ff")255 hexToDec("100")256 hexToDec("ABCDEF")11259375 hexToDec("10")16

ヒント

main.py
main.py
学習モード

メモ

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

⌘S で保存