<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>archive</title><link>https://archive-w.netlify.app/corner/encoding/</link><description>Recent content on archive</description><generator>Hugo</generator><language>zh-CN</language><atom:link href="https://archive-w.netlify.app/corner/encoding/index.xml" rel="self" type="application/rss+xml"/><item><title/><link>https://archive-w.netlify.app/corner/encoding/varint/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://archive-w.netlify.app/corner/encoding/varint/</guid><description>&lt;ul>
&lt;li>
&lt;h2 id="introvarint-encoding">
 Intro(Varint-encoding)
 &lt;a class="anchor" href="#introvarint-encoding">#&lt;/a>
&lt;/h2>
&lt;ul>
&lt;li>
&lt;h3 id="定义描述">
 定义描述
 &lt;a class="anchor" href="#%e5%ae%9a%e4%b9%89%e6%8f%8f%e8%bf%b0">#&lt;/a>
&lt;/h3>
&lt;p class="warn">varint 类似于 utf-8，varchar等长度不定。顾名思义，属于变长的 int。对于一个 int 类型的数据来说，一般都为四个字节(固长)。所以变长的话就是将固定的四个字节中浪费的那部分去掉，比如对于整形 2 来说对应的二进制为 &lt;span class="math inline">\(00000000\space00000000\space00000000\space{\color{red}00000010}\)&lt;/span> 前面的三个字节都为0，而且完全可以使用一个字节表示，此处对于整数2 来说，前三个字节就是浪费。所以出现了&lt;code>varint&lt;/code>。使用少量字节来表示整数。使用定义型的方式描述就是：&lt;strong>采用不定长的字节来编码或序列化一个整数&lt;/strong>。&lt;/p>
&lt;/li>
&lt;li>
&lt;h3 id="编码过程">
 编码过程
 &lt;a class="anchor" href="#%e7%bc%96%e7%a0%81%e8%bf%87%e7%a8%8b">#&lt;/a>
&lt;/h3>
&lt;div class="alert callout note">&lt;p class="title">&lt;span class="icon icon-note">&lt;/span> Note &lt;/p>&lt;p> 将一个 int 型的数据二进制表示，从后至前，依次取 7 位，与 varint 特性 msb 占 1 位组成一个字节，直到无效字节(也就是前面全是零)，然后将这些字节按照小端字节序排列。形成一个新的数字，这个过程中会丢弃浪费字节，达到压缩的目的。
&lt;br>&lt;br>&lt;span style='color:red'>varint msb 最高有效位为 1 表示后面都得字节属于当前值，为 0 表示当前字节是最后一部分。用来区分 varint 值边界。&lt;/span>
&lt;br>&lt;br>&lt;span style='color:red'>对于负数来说，编码过程并没有什么区别，只是因为负数最高位一直为 1，所以不存在浪费，也就是 vaint 对于负数压缩无效，字节不减反增。原本 -2 可以使用 8 个字节表示，但最终用使用了 10 个字节。所以在 ProtoBuf 中一般只处理 无符号 64bit 值，签名如：&lt;code>func EncodeVarint(v uint64) []byte {}&lt;/code>。所以我们此处传入的 -2 其实是当一个无符号正值处理的，负数的 varint 编码没有意义，我们应当避免直接对负值进行 varint 编码。&lt;/span>&lt;span style='color:blue'>而是先进行 


 
 

 
 
 
 
 
 
 
 &lt;a href='../zigzag/' rel="noopener" class="internal-link" data-src="../zigzag/">zigzag 编码&lt;/a> 映射后在进行 varint处理。&lt;/span>&lt;/p></description></item><item><title/><link>https://archive-w.netlify.app/corner/encoding/zigzag/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://archive-w.netlify.app/corner/encoding/zigzag/</guid><description>&lt;ul>
&lt;li>
&lt;h2 id="introzigzag-encoding">
 Intro(ZigZag-encoding)
 &lt;a class="anchor" href="#introzigzag-encoding">#&lt;/a>
&lt;/h2>
&lt;ul>
&lt;li>
&lt;h3 id="定义描述">
 定义描述
 &lt;a class="anchor" href="#%e5%ae%9a%e4%b9%89%e6%8f%8f%e8%bf%b0">#&lt;/a>
&lt;/h3>
&lt;p class="warn">正如 


 
 

 
 
 
 
 
 
 
 &lt;a href='../varint/' rel="noopener" class="internal-link" data-src="../varint/">varint 编码&lt;/a> 中所述，它对于负数来说显得手足无措，心有余而力不足。&lt;strong>zigzag 编码&lt;/strong> 就是用来弥补 varint 的缺陷的。它会将负数映射成正值（但是不需要额外的映射表），比如：&lt;code>(0 = 0, -1 = 1, 1 = 2, -2 = 3, 2 = 4, -3 = 5, 3 = 6 ...)&lt;/code>，从而能够使用 varint 继续编码。zigzag 编码的大致原理就是采用异或操作，将阻碍压缩的 1 进行消除。
&lt;br>&lt;br>&lt;span style='color:blue'>没有特别说明的都已 32 bit 进行阐述。&lt;/span>&lt;/p>
&lt;div class="alert callout warning">&lt;p class="title">&lt;span class="icon icon-warning">&lt;/span> 异或操作 &lt;/p>&lt;p> 异或运算(&lt;code>XOR&lt;/code> | &lt;code>^&lt;/code>)，相同为 0，不同为 1。并且异或操作有如下特性：
&lt;br>&lt;span style='padding-left:2.0em'/>&lt;code>1).&lt;/code> 任何数（0，1）与 1 进行异或的结果相当于取反，比如 0 ^ 1 = 1, 1 ^ 1 = 0。
&lt;br>&lt;span style='padding-left:2.0em'/>&lt;code>2).&lt;/code> 任何数（0，1）与 0 进行异或的结果相当于不变，比如 0 ^ 0 = 0, 1 ^ 0 = 1。&lt;/p></description></item></channel></rss>