转换器

十六进制完全指南:Base-16 数制详解

学习十六进制(base-16)的工作原理,掌握十六进制与十进制的相互转换、十六进制在计算领域的作用、带符号十六进制与二进制补码、十六进制运算,以及 Python、JavaScript 和 C 的编程示例。

发布于 2026年3月19日
15 分钟阅读
密码学指南

十六进制完全指南:Base-16 数制详解

十六进制在计算领域无处不在。如果你曾见过 #FF5733 这样的网页颜色代码、0x7FFF5FBFF8AC 这样的内存地址,或者密码学哈希值,你就已经接触过十六进制数了。然而,许多开发者将十六进制视为一种神秘的记法,只是机械地复制粘贴,并不真正理解它。

本指南将改变这一现状。读完之后,你将能够准确理解十六进制数制的工作原理,在十六进制与十进制之间自由转换,并明白为什么十六进制是底层计算领域的主流记法。你可以使用我们的免费十六进制转十进制工具,边阅读边对下面的示例进行实操验证。

为什么是十六进制?2 的幂次关联

要理解十六进制为何存在,先从一个简单的问题出发:为什么不在计算中直接使用十进制?

答案在于二进制。计算机以二进制(base-2)运行,数据表示为 0 和 1 的序列。单个字节——计算机内存的基本单位——是 8 个二进制位(比特)。字节值 11010110 对计算机来说完全精确,但对人类来说它又长、又容易出错、又枯燥难读。

十进制(base-10)对人类来说是自然的,但它与二进制并不整齐对齐。在二进制和十进制之间转换需要除法和乘法运算,这会掩盖底层的位模式。

十六进制(base-16)解决了这个问题,因为 16 是 2 的幂次:16 = 2^4。这意味着每个十六进制数字恰好代表 4 个二进制位,两个十六进制数字恰好代表一个字节,对齐完美:

二进制(8 位)十六进制(2 位)十进制
0000 0000000
0111 11117F127
1000 000080128
1111 1111FF255

字节值 11010110 在十六进制中只需 D6 两个字符,直接映射到底层位,无需任何运算。这正是十六进制成为计算领域首选记法的原因。

十六进制数字:0-9 与 A-F

十六进制使用十六个符号来表示零到十五的值:

十六进制数字十进制值二进制
000000
110001
220010
330011
440100
550101
660110
770111
881000
991001
A101010
B111011
C121100
D131101
E141110
F151111

字母 A 到 F 在十个十进制数字之外,用于表示 10 到 15 的值。大写(A-F)和小写(a-f)在几乎所有场合都被接受,但大写是约定俗成的标准。

常用十六进制前缀与记法

不同的编程语言和场景使用不同的记法来标识十六进制数:

  • 0x — C、C++、Java、Python、JavaScript:0xFF
  • # — CSS 颜色代码:#FF5733
  • $ — 6502/68000 汇编:$FF
  • h 后缀 — Intel 汇编:FFh
  • U+ — Unicode 码点:U+0041
  • \x — 字符串中的十六进制转义:\x41(字母 A)

前缀或记法不会改变数值——它只是告诉解析器或读者将这些数字解释为十六进制。

如何将十六进制转换为十进制

核心技术是位值表示法——与所有数制的工作原理相同,只是以 16 为基数而非 10。

公式

对于一个由数字 d(n-1)、d(n-2)、……、d(1)、d(0) 组成的十六进制数,其十进制值为:

十进制 = d(n-1) × 16^(n-1) + d(n-2) × 16^(n-2) + … + d(1) × 16^1 + d(0) × 16^0

每个十六进制数字乘以 16 的对应位次幂(从右向左,从 0 开始计数),再将所有乘积相加。

16 的幂次参考表

记住前几个 16 的幂次,可以大幅加快心算转换速度:

幂次
16^01
16^116
16^2256
16^34,096
16^465,536
16^51,048,576
16^616,777,216
16^7268,435,456
16^84,294,967,296

示例一:将 2F 转换为十进制

十六进制输入: 2F

  1. 数字 2 位于第 1 位:2 × 16^1 = 2 × 16 = 32
  2. 数字 F(15)位于第 0 位:15 × 16^0 = 15 × 1 = 15
  3. 求和:32 + 15 = 47

结果: 2F(十六进制)= 47(十进制)

示例二:将 1A3F 转换为十进制

十六进制输入: 1A3F

  1. 数字 1 位于第 3 位:1 × 16^3 = 1 × 4,096 = 4,096
  2. 数字 A(10)位于第 2 位:10 × 16^2 = 10 × 256 = 2,560
  3. 数字 3 位于第 1 位:3 × 16^1 = 3 × 16 = 48
  4. 数字 F(15)位于第 0 位:15 × 16^0 = 15 × 1 = 15
  5. 求和:4,096 + 2,560 + 48 + 15 = 6,719

结果: 1A3F(十六进制)= 6,719(十进制)

示例三:将 DEADBEEF 转换为十进制

十六进制输入: DEADBEEF(一个著名的「hexspeak」值,常作为调试中的幻数使用)

  1. D(13)× 16^7 = 13 × 268,435,456 = 3,489,660,928
  2. E(14)× 16^6 = 14 × 16,777,216 = 234,881,024
  3. A(10)× 16^5 = 10 × 1,048,576 = 10,485,760
  4. D(13)× 16^4 = 13 × 65,536 = 851,968
  5. B(11)× 16^3 = 11 × 4,096 = 45,056
  6. E(14)× 16^2 = 14 × 256 = 3,584
  7. E(14)× 16^1 = 14 × 16 = 224
  8. F(15)× 16^0 = 15 × 1 = 15

求和:3,489,660,928 + 234,881,024 + 10,485,760 + 851,968 + 45,056 + 3,584 + 224 + 15 = 3,735,928,559

这是一个 32 位无符号整数,调试工具常用它来标记未初始化内存。

如何将十进制转换为十六进制

反向过程使用反复除以 16 的方法:

  1. 将十进制数除以 16
  2. 记录余数(作为一个十六进制数字)
  3. 用商替换当前数
  4. 重复上述步骤,直到商为 0
  5. 从下往上读取十六进制数字(最后的余数在最前面)

示例:将 6,719 转换为十六进制

步骤运算余数十六进制数字
16719 / 1641915F
2419 / 162633
326 / 16110A
41 / 16011

从下往上读:1A3F

验证:1A3F(十六进制)= 1×4096 + 10×256 + 3×16 + 15×1 = 4096 + 2560 + 48 + 15 = 6,719。正确。

十六进制在计算领域的应用

内存地址

调试程序时,内存地址以十六进制显示:

0x7FFF5FBFF8AC
0x00400000(Linux 上 .text 节的典型起始地址)
0xDEADBEEF(未初始化内存的调试标记)

使用十六进制是因为内存是按字节寻址的,两个十六进制数字映射到一个字节。一个 64 位地址如 0x7FFF5FBFF8AC 是 12 个十六进制数字——远比它所表示的 48 个二进制数字更易读。

网页颜色代码

CSS 十六进制颜色编码红、绿、蓝三种强度值:

十六进制代码R(十进制)G(十进制)B(十进制)颜色
#000000000黑色
#FFFFFF255255255白色
#FF000025500红色
#00FF0002550绿色
#0000FF00255蓝色
#FF57332558751橙红色
#3A7BD558123213钢蓝色

每对十六进制数字代表一个字节(十进制 0-255),你可以使用我们的十六进制转十进制工具转换这些值。完整的 RGB 分解,可以使用我们的十六进制转 RGB 工具

MAC 地址

网络接口地址由六对十六进制字节组成,以冒号或连字符分隔:

00:1A:2B:3C:4D:5E

前三个字节(00:1A

)标识制造商(OUI),后三个字节(3C:4D
)是设备专属标识符。每对字节对应一个十六进制字节,转换为十进制值范围是 0-255。

Unicode 码点

每个 Unicode 字符都有一个以十六进制写成的码点:

码点十六进制值十进制字符
U+00414165A
U+00484872H
U+00E9E9233é(带重音)
U+4E164E1619,990世(中文「世界」)
U+1F6001F600128,512笑脸表情符号

十六进制记法之所以被使用,是因为它与底层字节编码(UTF-8、UTF-16)对齐,并且对整个 Unicode 范围(0 到 10FFFF)来说比十进制更紧凑。

每位开发者都应了解的常见十六进制值

某些十六进制值在编程和系统管理中出现频率极高,能够立刻认出它们可以节省大量时间。

字节边界

十六进制十进制含义
0x000空字节,C 中的字符串终止符
0x0A10换行符(LF),Unix 换行
0x0D13回车符(CR)
0x2032ASCII 空格字符
0x7F127有符号 8 位整数最大值,DEL 字符
0x80128有符号 8 位最小值(二进制补码)
0xFF255无符号 8 位最大值(1 字节)
0xFFFF65,535无符号 16 位最大值
0xFFFFFFFF4,294,967,295无符号 32 位最大值

ASCII 字符十六进制范围

十六进制范围十进制范围字符
30-3948-57数字 '0' 到 '9'
41-5A65-90大写字母 'A' 到 'Z'
61-7A97-122小写字母 'a' 到 'z'

了解大写字母 A 从 0x41(65)开始,小写字母 a 从 0x61(97)开始——两者相差恰好 0x20(32)——在低级代码中实现大小写转换时非常有用。

调试与幻数

程序员使用可识别的十六进制模式来标记特殊的内存状态:

十六进制十进制用途
0xDEADBEEF3,735,928,559未初始化内存标记(IBM)
0xCAFEBABE3,405,691,582Java 类文件幻数
0xBAADF00D3,131,961,357Windows LocalAlloc 未初始化堆
0xFEEDFACE4,277,009,102Mach-O 二进制头(macOS)
0xDEADC0DE3,735,929,054OpenSolaris 未初始化缓冲区标记

这些「hexspeak」值之所以被选中,是因为它们在内存转储中醒目易辨,同时只使用十六进制有效字母(A-F)。

带符号十六进制与二进制补码

在大多数现代计算机中,负整数使用二进制补码编码存储。理解这一点对于解读内存转储、寄存器值和网络协议中的有符号十六进制值至关重要。

二进制补码的工作原理

对于 N 位有符号整数:

  • 如果最高有效位(MSB)为 0,则数为正数(或零)
  • 如果 MSB 为 1,则数为负数

从 MSB 被置位的十六进制数中求负值:

  1. 转换为二进制
  2. 对所有位取反(0 变 1,1 变 0)
  3. 加 1
  4. 结果为绝对值,在前面加负号

8 位有符号十六进制示例

十六进制二进制无符号值有符号值(8 位)
000000000000
7F01111111127+127(最大正值)
8010000000128-128(最小负值)
FF11111111255-1
FE11111110254-2
8110000001129-127

示例:0x9C 作为有符号 8 位整数是多少?

  1. 二进制:10011100
  2. MSB 为 1,因此是负数
  3. 取反:01100011
  4. 加 1:01100100 = 十进制 100
  5. 结果:-100

因此,0x9C 作为无符号字节是 156,作为有符号字节则是 -100。解释完全取决于上下文。

16 位和 32 位有符号值

同样的原理适用于更宽的整数:

十六进制无符号值有符号值(32 位)
0000000000
7FFFFFFF2,147,483,647+2,147,483,647(最大)
800000002,147,483,648-2,147,483,648(最小)
FFFFFFFF4,294,967,295-1
FFFFFFFE4,294,967,294-2

十六进制运算

虽然大多数人使用计算器进行十六进制运算,但理解基本原理对调试和心算很有帮助。

十六进制加法

十六进制加法与十进制加法规则相同,只是进位阈值为 16 而非 10:

  3A
+ 1F
----
  1. 右列:A(10)+ F(15)= 25。因为 25 ≥ 16,写 25 - 16 = 9,进位 1
  2. 左列:3 + 1 + 1(进位)= 5

结果:3A + 1F = 59

验证:58 + 31 = 89(十进制)。59(十六进制)= 5×16 + 9 = 89。正确。

十六进制减法

  FF
- 3A
----
  1. 右列:F(15)- A(10)= 5
  2. 左列:F(15)- 3 = C(12)

结果:FF - 3A = C5

验证:255 - 58 = 197。C5(十六进制)= 12×16 + 5 = 197。正确。

快速心算技巧

  • F 加 1 等于 10(十六进制),而不是 16——记住你在十六进制中运算
  • FF + 1 = 100(十六进制)= 256(十进制)
  • 10(十六进制)减 1 等于 F
  • 将某个十六进制数字翻倍:将其十进制值翻倍,若 ≥ 16 则转换回十六进制

编程语言中的十六进制转十进制

Python

Python 的 int() 函数是解析十六进制字符串的标准方式:

# 十六进制字符串转十进制
result = int("FF", 16)     # 255
result = int("1A3F", 16)   # 6719

# 十六进制字面量
value = 0xFF               # 255

# 十进制转十六进制
hex(255)                    # '0xff'
format(255, 'X')            # 'FF'
format(255, '04X')          # '00FF'(补零填充)

# 带 0x 前缀解析
int("0xFF", 16)             # 255
int("0xFF", 0)              # 255(自动检测进制)

JavaScript

JavaScript 使用 parseInt() 解析十六进制字符串,0x 前缀用于字面量:

// 十六进制字符串转十进制
parseInt("FF", 16)          // 255
parseInt("1A3F", 16)        // 6719

// 十六进制字面量
const value = 0xFF;         // 255

// 十进制转十六进制
(255).toString(16)          // 'ff'
(255).toString(16).toUpperCase() // 'FF'

// 对超大值使用 BigInt
BigInt("0xDEADBEEFDEADBEEF") // 16045690984833335023n

// Number.parseInt 同样有效
Number.parseInt("FF", 16)   // 255

C / C++

C 使用 strtol() 进行字符串转换,并直接支持十六进制字面量:

#include <stdio.h>
#include <stdlib.h>

int main() {
    // 字符串转十进制
    long value = strtol("FF", NULL, 16);  // 255
    printf("%ld\n", value);

    // 十六进制字面量
    int x = 0xFF;            // 255
    printf("%d\n", x);       // 十进制:255
    printf("%X\n", x);       // 十六进制:FF
    printf("%08X\n", x);     // 补零填充:000000FF

    // 无符号 32 位
    unsigned long big = strtoul("DEADBEEF", NULL, 16);
    printf("%lu\n", big);    // 3735928559

    return 0;
}

常见问题

如何将十六进制转换为十进制?

将每个十六进制数字乘以其对应位次的 16 的幂次,然后将所有乘积相加。例如,十六进制 2F = 2×16 + 15×1 = 32 + 15 = 47。乘法前先将字母 A-F 替换为对应的十进制值(A=10、B=11、C=12、D=13、E=14、F=15)。

0xFF 的十进制是多少?

0xFF 在十进制中等于 255。F(15)× 16 + F(15)× 1 = 240 + 15 = 255。这是无符号 8 位字节的最大值(二进制 11111111),在编程中常用作位掩码。

0x 前缀是什么意思?

0x 前缀是 C、Java、Python、JavaScript 等众多语言中使用的记法约定,表示后续数字为十六进制。它不改变数值——0xFFFF 表示同一个数(十进制 255)。

如何将十进制转换为十六进制?

反复将十进制数除以 16,记录每次的余数。从下往上读取余数,即构成十六进制数。余数为 10-15 时使用字母 A-F。例如,255 / 16 = 15 余 15,然后 15 / 16 = 0 余 15。从下往上读:FF。

十六进制和十进制有什么区别?

十六进制是 base-16(数字 0-9 和 A-F),十进制是 base-10(仅数字 0-9)。十六进制在计算中更受青睐,因为每个十六进制数字恰好映射到 4 个二进制位,是二进制数据的紧凑表示。十进制是人类的标准计数系统。

如何将带符号的十六进制转换为十进制?

对于带符号十六进制值(二进制补码),检查最高有效位。如果被置位(8 位值中最左边位置的十六进制数字为 8-F),则数为负数。求绝对值:对所有位取反后加 1。例如,0xFF 作为有符号 8 位整数为 -1(11111111 取反得 00000000,加 1 得 1,取负得 -1)。

十六进制在哪些地方使用?

十六进制用于内存地址、网页颜色代码(#FF5733)、MAC 地址、Unicode 码点(U+0041)、密码学哈希值(SHA-256)、汇编语言、IPv6 地址,以及一切需要用紧凑易读记法表示二进制数据的场合。

为什么十六进制优于八进制?

十六进制与字节边界对齐:2 个十六进制数字 = 1 个字节(8 位)。八进制(base-8)使用 3 位分组,无法与 8 位字节整齐对齐。一个字节需要 2.67 个八进制数字,但恰好需要 2 个十六进制数字。这就是为什么十六进制在现代计算中基本取代了八进制,尽管八进制在 Unix 文件权限中依然存在(chmod 755)。

如何进行十六进制运算?

十六进制运算遵循与十进制运算相同的规则,只是进位/借位阈值为 16 而非 10。加法时,如果某列之和超过 15(F),则减去 16 并向下一列进位 1。减法时,如果某列之差为负,则加 16 并从下一列借位 1。

十六进制可以有小数点吗?

可以,尽管很少见。十六进制 1.8 等于十进制 1 + 8/16 = 1.5。某些编程场景(C99 的 %a 格式、IEEE 754 十六进制浮点记法)使用十六进制浮点,如 0x1.8p3(表示 1.5 × 2^3 = 12.0)。实际上,大多数十六进制转十进制转换处理的是整数。

十六进制与其他数制的比较

了解十六进制与其他数制的比较,有助于明确何时使用哪种数制:

属性二进制(Base-2)八进制(Base-8)十进制(Base-10)十六进制(Base-16)
使用的数字0-10-70-90-9、A-F
每位二进制位数13~3.324
字节对齐完美(8 位)差(2.67 位)无(可变)完美(2 位)
主要用途硬件逻辑Unix 权限人类数学计算记法

在计算场景中,十六进制凭借完美的字节对齐占据优势。八进制在 Unix 文件权限(chmod 755 = rwxr-xr-x)中依然存在,因为 3 位分组与读/写/执行权限模型完美匹配。十进制仍然是面向人类的值(如价格、计数和度量)的标准。

如需在这些数制之间转换,可以使用我们的二进制转十进制工具二进制转八进制工具,配合十六进制转十进制工具一起使用。

小结

十六进制是人类可读记法与计算机二进制现实之间的桥梁。它的力量来自一个简单的数学事实:16 = 2^4,因此每个十六进制数字恰好映射到 4 个二进制位。这种对齐使十六进制成为紧凑表达二进制数据的自然方式。

本指南的核心要点:

  • 十六进制转十进制:将每位数字乘以其对应的 16 的幂次,再将乘积相加
  • 十进制转十六进制:反复除以 16,从下往上收集余数
  • 两个十六进制数字 = 一个字节:FF = 255,无符号字节的最大值
  • 带符号十六进制使用二进制补码——同样的 8 位可以表示 255(无符号)或 -1(有符号)
  • 十六进制运算遵循标准规则,进位阈值为 16
  • 编程:Python int("FF", 16)、JavaScript parseInt("FF", 16)、C strtol("FF", NULL, 16)

准备好转换了吗?使用我们的免费十六进制转十进制工具,即时将任意十六进制值转换为十进制,并获得逐步位值表示法分解。你也可以探索我们的十六进制转二进制工具十六进制转文本工具,进行相关转换。

关于本文

本文是我们综合 转换器 教程系列的一部分。继续了解古典密码学,并探索我们的交互式密码工具。

更多 转换器 教程

试用 转换器 工具

通过我们的交互式转换器工具,将所学知识付诸实践。

试用 转换器 工具