-
-
Save RandyMcMillan/f5328a4e33ee77c90d4e89684b944a4b to your computer and use it in GitHub Desktop.
varint_bitcoin.rs
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 | |
| } |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
https://play.rust-lang.org/?version=stable&mode=debug&edition=2024&gist=87a47ecc26e26be1c44699d0309f1091