Search code examples
binarynumbersbitcoincrystal-lang

How to manipulate binary numbers efficiently in Crystal?


I'm trying to implement the Bitcoin specification BIP-39, specifically the part Generating the mnemonic. The following causes some headaches:

Next, these concatenated bits are split into groups of 11 bits, each encoding a number from 0-2047, serving as an index into a wordlist. Finally, we convert these numbers into words and use the joined words as a mnemonic sentence.

Splitting a binary number into groups of 11 bits. But how would I do this efficiently in Crystal?

Here is what I do, I personally find it a bit embarrassing but admittedly it works:

seed = "87C1B129FBADD7B6E9ABC0A9EF7695436D767AECE042BEC198A97E949FCBE14C0d"
# => "87C1B129FBADD7B6E9ABC0A9EF7695436D767AECE042BEC198A97E949FCBE14C0d"

bin = BigInt.new(seed, 16).to_s(2)
# => "100001111100000110110001001010011111101110101101110101111011011011101001101010111100000010101001111011110111011010010101010000110110110101110110011110101110110011100000010000101011111011000001100110001010100101111110100101001001111111001011111000010100110000001101"

iter = 0
size = 11
while iter < bin.size
  p bin[iter, size]
  # => "10000111110"
  # [...]
end

Now, as I said, it works, I can take the binary strings and convert them back to numbers and continue, but this cannot be it. I'm wondering, what is a more elegant, more efficient, or more correct way to approach this?


Solution

  • Sorry for the succinct answer, but I think what you're looking for is BitArray. Hope it serves you well!