가변 길이 정수
비트코인에서 길이를 표시할 때 공간을 절약하기 위해 종종 가변 길이를 사용한다. 가변길이로 이루어진 정수(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);
}
}
//...생략...
}