가변 길이 정수
비트코인에서 길이를 표시할 때 공간을 절약하기 위해 종종 가변 길이를 사용한다. 가변길이로 이루어진 정수(Variable length integer)는 아래와 같이 숫자 범위에 따라 1 ~ 9 바이트까지 가변적인 바이트 배열에 값을 저장하게 된다. 가변 길이 정수가 2 바이트 이상의 배열인 경우, 정수값은 리틀 엔디안(Little endian) 형태로 저장된다.
숫자 범위 | 바이트 수 | 저장 포맷 |
---|---|---|
< 0xFD | 1 | 길이 (직접입력) |
<= 0xFFFF | 3 | 0xFD + 길이(2 바이트) |
<= 0xFFFFFFFF | 5 | 0xFE + 길이(4 바이트) |
> 0xFFFFFFFF | 9 | 0xFF + 길이(8 바이트) |
가변 길이 정수는 C#에서 이를 아래와 같이 VarInt 타입으로 정의할 수 있다.
public class VarInt { public ulong Value { get; private set; } // number bytes are stored in little-endian public byte[] Bytes { get; private set; } public VarInt(int number) : this((ulong)number) { } public VarInt(ulong number) { this.Value = number; if (number <= 0xfc) { Bytes = new byte[1]; Bytes[0] = (byte)number; } else if (number <= 0xffff) { Bytes = new byte[3]; Bytes[0] = 0xfd; byte[] num = BitConverter.GetBytes((UInt16)number); Array.Copy(num, 0, Bytes, 1, 2); } else if (number <= 0xffffffff) { Bytes = new byte[5]; Bytes[0] = 0xfe; byte[] num = BitConverter.GetBytes((UInt32)number); Array.Copy(num, 0, Bytes, 1, 4); } else { Bytes = new byte[9]; Bytes[0] = 0xff; byte[] num = BitConverter.GetBytes(number); Array.Copy(num, 0, Bytes, 1, 8); } } //...생략... }