F

二进制与十六进制调试手册:位运算、掩码与颜色值的进制思维Binary and Hex Debugging Handbook: Bitwise Ops, Masks and Thinking in Bases for Colour Values

日志里打出 `0xFFFFFF00` 不是乱码,权限位 `0755` 不是十进制,颜色 `#FF8800` 也不是魔法字符串。本文用一线调试中的真实案例,讲清二进制、十六进制与位运算如何帮你快速定位问题。`0xFFFFFF00` in a log is not garbage, permission bits `0755` are not decimal, and colour `#FF8800` is not a magic string. This article uses real debugging cases to show how binary, hexadecimal and bitwise operations help you locate problems fast.

为什么调试时总绕不开十六进制Why hex keeps showing up during debugging

十六进制的本质是"二进制的紧凑写法":4 个二进制位恰好对应 1 个十六进制位,所以一个字节(8 位)用两个十六进制字符就能表示。`0xFF` 就是 `11111111`,`0x0A` 就是 `00001010`。当你需要看一个 32 位整数的每一位时,写成 `0xDEADBEEF` 比写 32 个 0 和 1 可读得多。Hexadecimal is essentially "a compact way to write binary": four binary bits map exactly to one hex digit, so a byte (8 bits) fits in two hex characters. `0xFF` is `11111111`, and `0x0A` is `00001010`. When you need to inspect every bit of a 32-bit integer, writing `0xDEADBEEF` is far more readable than 32 zeros and ones.

我第一次真正体会到十六进制的价值是排查一个网络协议问题:抓包工具里显示字段值是 `0x00000100`,十进制是 256,但协议文档里这个字段应该是"小端序的 1"。把 256 写成十六进制 `0x0100` 后立刻看出来——字节序反了,正确值应该是 `0x0001`(十进制 1)。如果只看十进制 256,根本不会联想到字节序问题。从那以后我养成了习惯:只要涉及位、标志、协议字段,第一反应是转成十六进制看结构。The first time I truly appreciated hex was debugging a network protocol issue: a packet capture showed a field value of `0x00000100`, which is 256 in decimal, but the protocol spec said this field should be "1 in little-endian". Writing 256 as `0x0100` made it instantly obvious — the byte order was reversed, and the correct value should be `0x0001` (decimal 1). Looking only at decimal 256, I would never have suspected endianness. Since then it has become a habit: whenever bits, flags or protocol fields are involved, my first move is to convert to hex and inspect the structure.

位运算与掩码:把一个整数当布尔数组用Bitwise ops and masks: treating an integer as a boolean array

位运算的核心是"逐位操作":`&`(按位与)可以提取特定的位,`|`(按位或)可以设置位,`^`(按位异或)可以翻转位,`~`(按位取反)可以全部翻转,`<<` 和 `>>` 可以移位。配合掩码(mask)——一个只有目标位为 1 的整数——就能在一个数字里塞进几十个布尔标志。The core of bitwise operations is "per-bit manipulation": `&` (AND) extracts specific bits, `|` (OR) sets bits, `^` (XOR) flips bits, `~` (NOT) flips all bits, and `<<` / `>>` shift them. Combined with a mask — an integer where only the target bits are 1 — you can pack dozens of boolean flags into a single number.

Linux 文件权限就是最经典的例子:`0755` 是八进制,但拆开看每一位都是二进制标志。所有者权限 `7` = `111`(读+写+执行),组权限 `5` = `101`(读+执行),其他用户 `5` = `101`。我在写一个部署脚本时,把权限写成了十进制 `755` 而不是八进制 `0755`,结果实际设置的权限完全不对——`755` 十进制转成二进制是 `1011110011`,和 `0755` 八进制(`111101101`)根本不是一回事。这个 bug 看起来很低级,但在 Python 3 里八进制必须写 `0o755`,JavaScript 里严格模式不允许 `0755` 这种前导零写法,不同语言的字面量规则不一样,稍不注意就踩坑。Linux file permissions are the classic example: `0755` is octal, but each digit breaks down into binary flags. Owner permission `7` = `111` (read+write+execute), group `5` = `101` (read+execute), others `5` = `101`. I once wrote a deployment script with the permission as decimal `755` instead of octal `0755`, and the actual permissions set were completely wrong — decimal 755 in binary is `1011110011`, which is nothing like octal `0755` (`111101101`). It seems like a trivial bug, but in Python 3 octal must be written as `0o755`, and in JavaScript strict mode a leading-zero `0755` is not allowed — literal rules differ across languages, and it is easy to slip up.

颜色值的进制思维:#RRGGBB 不是字符串是整数Thinking in bases for colour: #RRGGBB is not a string, it is an integer

前端最常见的十六进制场景就是颜色值。`#FF8800` 看起来是个字符串,但本质上是一个 24 位整数:高 8 位是红(FF=255),中 8 位是绿(88=136),低 8 位是蓝(00=0)。理解了这一点,颜色的混合、透明度叠加、取反色都可以用位运算完成,而不需要调一堆字符串处理函数。The most common hex scenario in frontend is colour values. `#FF8800` looks like a string, but it is fundamentally a 24-bit integer: the high 8 bits are red (FF=255), the middle 8 bits green (88=136), and the low 8 bits blue (00=0). Once you understand this, colour mixing, alpha compositing and inversion can all be done with bitwise operations — no string-processing functions required.

比如从颜色值中提取红色分量:`(color >> 16) & 0xFF`。先右移 16 位把红色移到最低字节,再用 `0xFF` 掩码把高位清零。设置蓝色分量则是 `(color & 0xFFFF00) | blue`,先用掩码清掉蓝色位,再或上新值。我在做一个图片水印工具时,需要把水印颜色的透明度和背景混合,一开始用字符串拆分 `#RRGGBB` 再 parseInt,代码又长又慢;改成整数位运算后,核心逻辑就三行,性能也提升了一个数量级。带 Alpha 通道的 `#RRGGBBAA` 同理,只是变成 32 位整数,多了一次 `>> 24` 提取透明度。For example, extracting the red component from a colour value: `(color >> 16) & 0xFF`. Shift right by 16 to move red to the lowest byte, then mask with `0xFF` to clear the high bits. Setting the blue component is `(color & 0xFFFF00) | blue` — first mask out the blue bits, then OR in the new value. I once built an image watermark tool that needed to blend the watermark colour's alpha with the background. My first approach split the `#RRGGBB` string and called parseInt — the code was long and slow. Switching to integer bitwise ops reduced the core logic to three lines and improved performance by an order of magnitude. Alpha-aware `#RRGGBBAA` works the same way, just as a 32-bit integer with one extra `>> 24` to extract alpha.

调试工具箱:进制转换是第一反应A debugging toolbox: base conversion is the first reflex

总结一下我在一线调试中总结的进制思维:看到标志位、权限、协议字段、颜色值,先转十六进制看结构;看到十进制异常值,想想是不是八进制或字节序搞错了;需要提取或设置某几位,用掩码+位运算而不是字符串操作。这些习惯不能让你写出更炫的代码,但能让你在排查"为什么这个值不对"时少走几个小时的弯路。To summarise the base-thinking habits I have picked up from on-the-ground debugging: when you see flags, permissions, protocol fields or colour values, convert to hex first and inspect the structure; when a decimal value looks wrong, consider whether octal or endianness is the culprit; when you need to extract or set specific bits, use masks and bitwise ops rather than string manipulation. These habits will not make your code flashier, but they will save you hours of detours when debugging "why is this value wrong".

本站的进制转换工具支持二进制、八进制、十进制、十六进制之间的互转,也能直接显示一个整数的位模式。排查权限位、颜色值、协议字段时,把值贴进去立刻就能看到各进制下的表示和每一位的开关状态,比心算或查计算器快得多。Our number-base tool converts between binary, octal, decimal and hexadecimal, and can display the bit pattern of an integer directly. When debugging permission bits, colour values or protocol fields, paste the value in and you instantly see its representation in every base plus the on/off state of each bit — much faster than mental arithmetic or reaching for a calculator.

← 返回教程列表← Back to all guides