![深入理解序列化与反序列化](https://wfqqreader-1252317822.image.myqcloud.com/cover/521/34667521/b_34667521.jpg)
1.5 ZigZag编码
1.5.1 ZigZag编码流程
ZigZag将有符号整数统一映射为无符号整数,再通过Varint编码规则达到数据压缩的效果。ZigZag的编码流程如下:
1)将整数补码最高位移到最低位。正整数的最高位为0,数值越小,高位的0越多。负整数的最高位为1,绝对值越小,高位的1越多。以整数1为例,最高位移位操作如表1-12所示。
表1-12 整数1的最高位移位操作
![img](https://epubservercos.yuewen.com/171F30/18519308908425106/epubprivate/OEBPS/Images/txt002_24.jpg?sign=1739292418-yfnpTCOjinN5D7lfv2oc9j3ERyDmPKs1-0-a176329e2c4636d17da2269fd2bd9ba2)
以整数-1为例,最高位移位操作如表1-13所示。
表1-13 整数-1的最高位移位操作
![img](https://epubservercos.yuewen.com/171F30/18519308908425106/epubprivate/OEBPS/Images/txt002_25.jpg?sign=1739292418-6KIGW4ZU2Z67O4GX8BX5I5rVOvQ4cuFf-0-aa12adf22444ade4c439d6edaae205a8)
从表1-13可以看出,负数绝对值越小,包含的前导1越多,用Varint编码压缩效果越差。
2)如果是负数,除符号位外,其他位取反;正数无须操作。这一步获得的便是ZigZag编码。以整数1为例,ZigZag编码的过程如表1-14所示。
表1-14 整数1的ZigZag编码过程
![img](https://epubservercos.yuewen.com/171F30/18519308908425106/epubprivate/OEBPS/Images/txt002_26.jpg?sign=1739292418-vlsbSW0ZmQLlVqiExpQYNpRuekyNE1AN-0-7119337455dc04b2bc4929a135ffa577)
以整数-1为例,ZigZag编码的过程如表1-15所示。
表1-15 整数-1的ZigZag编码过程
![img](https://epubservercos.yuewen.com/171F30/18519308908425106/epubprivate/OEBPS/Images/txt002_27.jpg?sign=1739292418-eWCwQkHusiNLrJGYeasB3aJIPEUvEjpW-0-da85517bd0011a73453b9abb70dd94b9)
0的ZigZag编码和补码一致,读者可自行验证。
至此,正整数、0、负整数都可以用ZigZag编码来表示了。
1.5.2 ZigZag编码算法实现
ZigZag编码算法实现如以下代码所示。
![img](https://epubservercos.yuewen.com/171F30/18519308908425106/epubprivate/OEBPS/Images/txt002_28.jpg?sign=1739292418-bdma1z8tZ2XAmvadE8jH5TKUWfJEMiyj-0-bebbbad25a3f54308251f7bad1d23e83)
上述代码看起来并不太好理解,下面通过步骤分解的方式来分析代码要表达的意思,如表1-16所示。
表1-16 ZigZag编码算法步骤分解
![img](https://epubservercos.yuewen.com/171F30/18519308908425106/epubprivate/OEBPS/Images/txt002_29.jpg?sign=1739292418-fByFu9FoQBtBqGXMC8xpQZsqyGNOF8fF-0-47c5b1303b32096a5d7b0d891a4ec53f)
1)n << 1:表示将整个值左移1位,正数、0、负数的最后1位就变成了0。
2)n >> 31:符号位放到最后1位。如果是非负数,则为全0;如果是负数,就是全1。
3)异或操作后可以看到,数据位全部反转了,而符号位保持不变,且移动到了最后1位。
1.5.3 ZigZag反编码流程
ZigZag反编码流程如下:
1)如果最低位是1,表示是负数,除符号位外,其他位取反;如果最低位是0,表示是正数,无须操作。以整数1为例,ZigZag反编码如表1-17所示。
表1-17 整数1的ZigZag反编码
![img](https://epubservercos.yuewen.com/171F30/18519308908425106/epubprivate/OEBPS/Images/txt002_30.jpg?sign=1739292418-s5PRgGUMERjAhW6cVdpjfJxqXUOSbWKa-0-1f44e9509374d5561427ced78f525196)
以整数-1为例,ZigZag反编码如表1-18所示。
表1-18 整数-1的ZigZag反编码
![img](https://epubservercos.yuewen.com/171F30/18519308908425106/epubprivate/OEBPS/Images/txt002_31.jpg?sign=1739292418-SS3UL2wSFUypm7R3AhpWiihRf8mmN83J-0-6780b1b63cc02b16d11aa5c4c87e4eb5)
2)将整数补码最低位移到最高位。以整数1为例,最低位移位操作如表1-19所示。
表1-19 整数1的最低位移位操作
![img](https://epubservercos.yuewen.com/171F30/18519308908425106/epubprivate/OEBPS/Images/txt002_32.jpg?sign=1739292418-JTLTL8buUA685wYySb9iDT4OXUWCamEp-0-8f98feacf112465eaad43989e139671e)
以整数-1为例,最低位移位操作如表1-20所示。
表1-20 整数-1的最低位移位操作
![img](https://epubservercos.yuewen.com/171F30/18519308908425106/epubprivate/OEBPS/Images/txt002_33.jpg?sign=1739292418-AHBaG1f6Xq7J0Qqf39PYP2fLDtXDznM9-0-91642272e0163e75f772f60ec6fde1d0)
1.5.4 ZigZag反编码算法实现
ZigZag编码还原为整数的算法实现如以下代码所示。
![img](https://epubservercos.yuewen.com/171F30/18519308908425106/epubprivate/OEBPS/Images/txt002_34.jpg?sign=1739292418-34hUuAgK7HRP8jlwkSzsYYcJOlMl9BVa-0-d82ae92dd965c2c378afe70a462e4b02)
上述代码看起来也不太好理解,依然通过步骤分解的方式来分析代码要表达的意思,如表1-21所示。
表1-21 ZigZag反编码算法步骤分解
![img](https://epubservercos.yuewen.com/171F30/18519308908425106/epubprivate/OEBPS/Images/txt002_35.jpg?sign=1739292418-TNEIwBbd0BbVyeLwJBC6QMAY0JCk1eqc-0-10b838a11e52e822506e6df9ebb598f6)
1.5.5 总结
ZigZag编码使用的前提是:在大多数情况下使用的数字都是小整数,比如用户年龄、班级、年级、购物数量等。当数字比较大的时候,需要5字节来表示整数。ZigZag编码机制被用于Thrift、Protocol Buffer、Avro等序列化方案中。