-
-
Save rust-play/87a47ecc26e26be1c44699d0309f1091 to your computer and use it in GitHub Desktop.
Code shared from the Rust Playground
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /// A verbose example of Bitcoin's two variable integer types. | |
| fn main() { | |
| let value: u64 = 515; | |
| // 1. CompactSize (Little-Endian) - Used in P2P/Transactions | |
| let compact = encode_compact_size(value); | |
| println!("Value: {}", value); | |
| println!("CompactSize (LE-based) hex: {:02x?}", compact); | |
| // 2. VarInt (Base-128 Big-Endian) - Used in LevelDB/Disk | |
| let varint = encode_varint(value); | |
| println!("Internal VarInt (BE-based) hex: {:02x?}", varint); | |
| } | |
| /// CompactSize: The standard "P2P" encoding (Little-Endian bytes after prefix) | |
| fn encode_compact_size(v: u64) -> Vec<u8> { | |
| if v < 253 { | |
| vec![v as u8] | |
| } else if v <= 0xFFFF { | |
| let mut b = vec![0xfd]; | |
| b.extend_from_slice(&(v as u16).to_le_bytes()); | |
| b | |
| } else if v <= 0xFFFFFFFF { | |
| let mut b = vec![0xfe]; | |
| b.extend_from_slice(&(v as u32).to_le_bytes()); | |
| b | |
| } else { | |
| let mut b = vec![0xff]; | |
| b.extend_from_slice(&v.to_le_bytes()); | |
| b | |
| } | |
| } | |
| /// VarInt: Internal Base-128 encoding (Big-Endian) | |
| /// Logic from Bitcoin Core's `serialize.h` / `WriteVarInt` | |
| fn encode_varint(mut n: u64) -> Vec<u8> { | |
| let mut res = Vec::new(); | |
| let mut tmp = Vec::new(); | |
| loop { | |
| // The last byte has MSB 0, others have MSB 1 | |
| let mask = if tmp.is_empty() { 0x00 } else { 0x80 }; | |
| tmp.push((n & 0x7F) as u8 | mask); | |
| if n <= 0x7F { break; } | |
| n = (n >> 7) - 1; // The "minus one" prevents redundant zero-padding | |
| } | |
| // Reverse because we calculated from least-significant to most-significant | |
| // but the format is Big-Endian. | |
| res.extend(tmp.into_iter().rev()); | |
| res | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment