lighttpd的buffer.c中有个int buffer_append_long_hex(buffer *b, unsigend long value),作用是把value转换成16进制字符串表示,并附加到buffer后面。
我提取了转换的操作,原理是这样的:
char hex_char[] = "0123456789abcdef"; char *h2x (char *buf, unsigned long value) { int shift = 0; /* 表示value 的二进制表示到底有多少位 */ unsigned long copy = value; char *org = buf; /* 获得value在16进制时的位数,保存在shift中 */ while (copy) { copy >>= 4; shift++; } /* 如果shift==0, 其实就是value == 0 */ if (shift == 0) { shift++; } /* 如果shift是奇数,我们要加1补成偶数,比如1234的16进制表示是0x4D2, 我们要把它扩展成0x04D2 */ if (shift & 0x01) { shift++; } /* 16进制的每一位数字都包含4个bit,所以乘4得到二进制表示的位数 */ shift <<= 2; while (shift > 0) { shift -= 4; /* 每次把需要的16进制位数移到最低的4位,并且&0x0F保证它落在数组中 */ *(buf++) = hex_char[(value >> shift) & 0x0F]; } *buf = '\0'; return org; }
可能说得还是不太清楚,举例来说,10进制1234的16进制表示是0x04D2,二进制表示则为 0000 0100 1101 0010,这段代码通过查表,把0000转成’0’,0100转成’4’……