가변 길이 정수
비트코인에서 길이를 표시할 때 공간을 절약하기 위해 종종 가변 길이를 사용한다. 가변길이로 이루어진 정수(Variable length integer)는 아래와 같이 숫자 범위에 따라 1 ~ 9 바이트까지 가변적인 바이트 배열에 값을 저장하게 된다. 가변 길이 정수가 2 바이트 이상의 배열인 경우, 정수값은 리틀 엔디안(Little endian) 형태로 저장된다.
숫자 범위 | 바이트 수 | 저장 포맷 |
---|---|---|
< 0xFD | 1 | 길이 (직접입력) |
<= 0xFFFF | 3 | 0xFD + 길이(2 바이트) |
<= 0xFFFFFFFF | 5 | 0xFE + 길이(4 바이트) |
> 0xFFFFFFFF | 9 | 0xFF + 길이(8 바이트) |
가변 길이 정수는 C#에서 이를 아래와 같이 VarInt 타입으로 정의할 수 있다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | 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); } } //...생략... } |