Protocol Buffer Varint Kodlayıcı

İşaretsiz bir tam sayı girerek protobuf varint olarak kodlayın.

Sonuç

ac 02
10101100 00000010
2 bayt

Nasıl hesaplanır?

Protobuf varint, işaretsiz bir tam sayıyı 7'şer bitlik gruplar halinde saklar; en düşük anlamlı grup önce gelir. Araç şunu tekrarlar: bayt = n & 0x7F, sonra n = n >> 7; n içinde değer kaldıysa bayta en üst bit eklenir (bayt | 0x80), yani devamında bayt vardır. n sıfır olunca döngü biter. Çıktıda her bayt onaltılık ve 8 haneli ikilik olarak, ayrıca bayt sayısı gösterilir. Rakamlar tam bir ondalık metin olarak işlendiği için 264 − 1'e (18446744073709551615; 10 bayt ister) kadar her değer tam kodlanır; daha büyük değerlerde sonuç çıkmaz. Kesir atılır (3,9 değeri 3 olur), 0 tek bayt olarak 00 kodlanır, negatif veya boş girdi sonuç vermez. Bu düz işaretsiz varint'tir; sint32 ve sint64 alanlarındaki zigzag biçimi ya da negatif int32/int64 için kullanılan 10 baytlık biçim değildir.

Örnek hesaplama

300 sayısını kodlayalım. İkilik düzende 300 = 100101100. Sağdan 7 bitlik gruplara bölünür: 0101100 (44) ve 10 (2). İlk grubun arkasında veri olduğu için en üst biti 1 yapılır: 10101100 = ac. Son grup 00000010 = 02 olarak kalır. Sonuç: ac 02, ikilik 10101100 00000010, toplam 2 bayt. Çözerken tersi yapılır: 0x2c + (2 << 7) = 44 + 256 = 300.

Bu örneği dene →

Sık yapılan hatalar

  • Baytları yanlış sırayla okumak: ilk bayt en düşük 7 biti taşır, bu yüzden ac 02 değeri 0x02ac değildir.
  • Her baytın en üst bitinin veri değil devam işareti olduğunu unutmak: bayt başına yalnızca 7 bit değer taşır, bu yüzden 128 bile 2 bayt ister (80 01).
  • Bu çıktıyı işaretli alan için kullanmak: sint32 ve sint64 önce zigzag ile kodlanır, yani −1 burada gösterildiği gibi kodlanmaz; araç zaten negatif sayıyı reddeder.
  • Alan etiketini beklemek: gerçek mesajda değerin önünde alan numarası ve tel tipinden oluşan bir etiket varint'i bulunur; araç yalnızca sayıyı kodlar.
  • 3,9 gibi ondalıklı bir sayının yuvarlanacağını sanmak: kesir yuvarlanmaz, atılır.

Bu hesaplama hakkında

Google'ın ikili serileştirme biçimi olan Protocol Buffers, küçük sayılardan tasarruf etmek için tam sayıları taban-128 varint ile kodlar: her bayt, değerin 7 bitini artı devam eden bayt varsa 1, son baytsa 0 olan bir "devam" bitini (en anlamlı bit) taşır. Bu sayede alan uzunlukları, enum değerleri ve kimlikler gibi gerçek dünyadaki protobuf mesajlarının büyük çoğunluğunu oluşturan küçük tam sayılar, sabit genişlikli bir tam sayının her zaman harcayacağı dört veya sekiz bayt yerine sadece bir baytta kodlanır; protobuf mesajlarının iletimde bu kadar kompakt kalmasının tek sebebi de budur.

Bu hesap makinesi işaretsiz bir tam sayıyı alır ve onu varint bayt dizisine kodlar, devam bitlerinin nasıl çalıştığını görebilmeniz için her baytı hem onaltılık hem de ikilik olarak gösterir. Protobuf wire format sorunlarını ayıklayan backend mühendisleri, üretilmiş bir kütüphane olmadan özel bir protobuf ayrıştırıcı veya serileştirici yazan geliştiriciler ve ikili kodlama şemalarını öğrenen öğrenciler, bir değerin bayt kodlamasının kendi kodlarının ürettiği veya beklediğiyle eşleştiğini elle doğrulamak için bu aracı kullanır.

Bu faydalı oldu mu?

En fazla 3 tepki seçebilirsiniz.

Yorumlar (1)

  • Editör ekibi

    Ofset ayıklarken uzunluk sınırlarını bilmek işe yarar: 127 hâlâ tek baytta (7f) durur, 128 iki bayt ister (80 01), 16384 ise üç bayt gerektiren ilk değerdir (80 80 01). Yani bir uzunluk öneki 127'yi aştığında kendinden sonraki her baytın yeri bir kayar. Kendi ayrıştırıcınızı yazıyorsanız sizi ilk hangi ayrıntı şaşırttı: devam biti mi, bayt sırası mı?

Popüler hesaplayıcılar

Tüm Hesaplayıcılar