這篇文章給大家介紹varint是什么意思,內(nèi)容非常詳細(xì),感興趣的小伙伴們可以參考借鑒,希望對(duì)大家能有所幫助。
尼金平網(wǎng)站建設(shè)公司創(chuàng)新互聯(lián)建站,尼金平網(wǎng)站設(shè)計(jì)制作,有大型網(wǎng)站制作公司豐富經(jīng)驗(yàn)。已為尼金平上千提供企業(yè)網(wǎng)站建設(shè)服務(wù)。企業(yè)網(wǎng)站搭建\成都外貿(mào)網(wǎng)站建設(shè)要多少錢,請(qǐng)找那個(gè)售后服務(wù)好的尼金平做網(wǎng)站的公司定做!
作為熟悉Kafka的讀者,肯定知道Kafka的消息中的很多長(zhǎng)度字段均采用了可變長(zhǎng)度的編碼格式,那么這種可變的編碼格式是什么呢,沒錯(cuò),就是我們今天要講的varint編碼格式。
計(jì)算機(jī)在信息傳輸?shù)倪^程中都是采用一定的編碼格式將數(shù)據(jù)編碼為二進(jìn)制,當(dāng)數(shù)據(jù)接收方收到數(shù)據(jù)以后也會(huì)進(jìn)行相應(yīng)的解碼將二進(jìn)制數(shù)據(jù)轉(zhuǎn)換成響應(yīng)的格式。在計(jì)算機(jī)中,一個(gè)二進(jìn)制數(shù)字(0或1)代表1Bit,8個(gè)Bit又稱為1個(gè)字節(jié)(byte)。
字節(jié)序指的就是多個(gè)字節(jié)在通信中的排列順序,字節(jié)序目前有兩種格式:
下圖就是數(shù)字123456的斷續(xù)和小端序的二進(jìn)制格式:
首先int類型的數(shù)據(jù)占據(jù)4個(gè)字節(jié),以大端序?yàn)槔覀兛梢钥吹?23456的高位的第一個(gè)字節(jié)都是無用的,我們可以使用三個(gè)字節(jié)就能代表123456,由于Kafka的長(zhǎng)度字段的數(shù)值都會(huì)遠(yuǎn)遠(yuǎn)小于123456,甚至1個(gè)字節(jié)也可以表示,如果我們依舊使用int來表示長(zhǎng)度的話將會(huì)浪費(fèi)大量的空間,因此基于這個(gè)原因,Kafka在自己的v2消息格式中的長(zhǎng)度字段具采用了可變長(zhǎng)度的表示,這種表示方式就是通過varint編碼。
varint其實(shí)并不僅僅在kafka中有所使用,大名鼎鼎的Protocol Buffers也使用varint編碼。
varint是使用一個(gè)或多個(gè)字節(jié)序列化整數(shù)的方式,他可以把一個(gè)固定字節(jié)的整數(shù)編碼成變長(zhǎng)字節(jié)。
varint編碼中每一個(gè)字節(jié)的最高位都不用來存儲(chǔ)數(shù)字的真正表示,而是表示當(dāng)前字節(jié)是否還屬于當(dāng)前數(shù)據(jù),1代表是,0代表不是(也就是該字節(jié)是當(dāng)前數(shù)據(jù)的最后一個(gè)字節(jié)數(shù)據(jù))。每一個(gè)字節(jié)的低7位用于以7位為一組存儲(chǔ)數(shù)字的二進(jìn)制補(bǔ)碼表示,最低有效數(shù)組在前,這也就表明varint編碼是按照小端序來排列的。
圖中對(duì)數(shù)字123456進(jìn)行varint編碼,123456用二進(jìn)制表示為1 11100010 01000000,每次低從向高取7位再加上最高有效位變成11000000 11000100 00000111。
下面我們通過一段Java代碼實(shí)現(xiàn)varint編碼和解碼,其中只實(shí)現(xiàn)了無符號(hào)Interger類型的數(shù)據(jù)。
關(guān)于varint是什么意思就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,可以學(xué)到更多知識(shí)。如果覺得文章不錯(cuò),可以把它分享出去讓更多的人看到。public class VarInt {
public static void writeUnsignedVarint(int value, DataOutput output) throws IOException {
// value & 0xffffff80 當(dāng)前字節(jié)是否為最后一個(gè)字節(jié),不是則執(zhí)行while
while ((value & 0xffffff80) != 0) {
// value & 0x7f保證可以取到整數(shù)最低7位
// | 0x80 填充字節(jié)最高位為1,因?yàn)楫?dāng)前字節(jié)還不是數(shù)據(jù)的最后一個(gè)字節(jié)
byte b = (byte) ((value & 0x7f) | 0x80);
output.writeByte(b);
System.out.println(b);
value >>>= 7 ;
}
// 寫入最后一個(gè)字節(jié)
System.out.println(value);
output.writeByte(value);
}
public static int readUnsignedVarint(ByteBuffer buffer) {
int value = 0;
int b;
int i = 0;
while (((b = buffer.get()) & 0x80) != 0) {
value |= (b & 0x7f) << i;
i += 7;
if (i >= 28) {
throw new IllegalArgumentException("illegal varint");
}
}
value |= b << i;
return value;
}
public static void main(String[] args) throws IOException {
DataOutputStream output = new DataOutputStream(new ByteArrayOutputStream(2));
writeUnsignedVarint(123456, output);
System.out.println("encode size:" + output.size());
System.out.println("-----------");
byte[] bytes = new byte[]{-64, -60, 7};
ByteBuffer wrap = ByteBuffer.wrap(bytes);
System.out.println("decode:" + readUnsignedVarint(wrap));
System.out.println("-----------");
}
}