Module: BSV::Transaction::VarInt
- Defined in:
- lib/bsv/transaction/var_int.rb
Overview
Bitcoin variable-length integer encoding/decoding.
VarInts encode unsigned integers compactly: values under 253 use a single byte; larger values use a marker byte followed by 2, 4, or 8 bytes in little-endian order.
Constant Summary collapse
- MAX_UINT64 =
Maximum value representable by a Bitcoin VarInt (unsigned 64-bit).
0xFFFF_FFFF_FFFF_FFFF
Class Method Summary collapse
-
.decode(data, offset = 0) ⇒ Array(Integer, Integer)
Decode a Bitcoin VarInt from binary data at the given offset.
-
.encode(value) ⇒ String
Encode an integer as a Bitcoin VarInt.
Class Method Details
.decode(data, offset = 0) ⇒ Array(Integer, Integer)
Decode a Bitcoin VarInt from binary data at the given offset.
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
# File 'lib/bsv/transaction/var_int.rb', line 41 def decode(data, offset = 0) raise ArgumentError, "truncated varint: need 1 byte at offset #{offset}, got end of data" if offset >= data.bytesize first = data.getbyte(offset) case first when 0..0xFC [first, 1] when 0xFD raise ArgumentError, "truncated varint: need 3 bytes at offset #{offset}, got #{data.bytesize - offset}" if data.bytesize < offset + 3 [data.byteslice(offset + 1, 2).unpack1('v'), 3] when 0xFE raise ArgumentError, "truncated varint: need 5 bytes at offset #{offset}, got #{data.bytesize - offset}" if data.bytesize < offset + 5 [data.byteslice(offset + 1, 4).unpack1('V'), 5] when 0xFF raise ArgumentError, "truncated varint: need 9 bytes at offset #{offset}, got #{data.bytesize - offset}" if data.bytesize < offset + 9 [data.byteslice(offset + 1, 8).unpack1('Q<'), 9] end end |
.encode(value) ⇒ String
Encode an integer as a Bitcoin VarInt.
21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
# File 'lib/bsv/transaction/var_int.rb', line 21 def encode(value) raise ArgumentError, "varint requires non-negative integer, got #{value}" if value.negative? raise ArgumentError, "varint value #{value} exceeds uint64 max (#{MAX_UINT64})" if value > MAX_UINT64 if value < 0xFD [value].pack('C') elsif value <= 0xFFFF [0xFD, value].pack('Cv') elsif value <= 0xFFFFFFFF [0xFE, value].pack('CV') else [0xFF, value].pack('CQ<') end end |