in3rsha/sha256-animation · error
(bitstring is not an exact amount of bytes)
Error message
(bitstring is not an exact amount of bytes)
What it means
bytes() in sha256lib.rb converts a binary input to an Array of byte integers, but only when the bit count after the 0b prefix is an exact multiple of 8 (bin.size % 8 == 0, one byte per 8 bits). When it is not, the function does not exit — it assigns this parenthesised note, a String, and returns it in place of the byte Array. Callers that assume an Array then fail later and elsewhere, typically with NoMethodError (undefined method 'map' for a String), so the root cause is easy to lose.
Source
Thrown at sha256lib.rb:102
puts "Invalid hex string: #{input}"
exit
end
return "hex"
else
return "string"
end
end
end
# Convert input (hex, ascii) to array of bytes
def bytes(input, type)
case type
when "binary"
bin = input[2..-1] # trim 0b prefix
if (bin.size % 8 == 0) # if we have been given a bitstring that makes up an exact number of bytes (8 bits in a byte)
bytes = bin.scan(/.{8}/).map {|byte| byte.to_i(2)} # convert the bits to array of bytes (in decimal)
else
bytes = "(bitstring is not an exact amount of bytes)" # helpful note
end
when "hex"
hex = input[2..-1] # trim 0x prefix
bytes = [hex].pack("H*").unpack("C*") # convert hex string to bytes
else
bytes = input.bytes # convert ASCII string to bytes
end
return bytes
end
# ----------
# Operations
# ----------
# Addition modulo 2**32
def add(*x)
total = x.inject(:+)
return total % 2 ** 32 # limits result of addition to 32 bitsView on GitHub (pinned to 871e976d69)
Solutions
- Pad the bit payload with leading zeros to a whole number of bytes: 0b101 becomes 0b00000101
- When the bits came from an integer, format in byte units up front: x.to_s(2).rjust(((x.bit_length + 7) / 8) * 8, '0')
- If an odd bit count means a character was lost in transit, re-derive the value instead of padding blindly
- In your own wrapper, raise ArgumentError when (input[2..].size % 8) != 0 rather than consuming the sentinel String
Example fix
# before
bytes('0b101010101', 'binary')
# => '(bitstring is not an exact amount of bytes)' — a String, not data
bytes('0b101', 'binary').map { |b| b }
# => NoMethodError: undefined method 'map' for String
# after
bytes('0b0000000010101010', 'binary')
# => [0, 170] Defensive patterns
Strategy: type-guard
Validate before calling
bits = input[2..].to_s raise ArgumentError, 'bitstring must be a whole number of bytes, got ' + bits.size.to_s + ' bits' unless (bits.size % 8).zero? byte_array = bytes(input, 'binary')
Type guard
def byte_array?(result)
result.is_a?(Array) && result.all? { |b| b.is_a?(Integer) && b.between?(0, 255) }
end
result = bytes(input, input_type(input))
raise TypeError, 'bytes() returned a sentinel note instead of data: ' + result.inspect unless byte_array?(result) Prevention
- Always emit bit strings in whole-byte lengths — pad leading zeros up to the next multiple of 8
- Never assume bytes() returns an Array; for misaligned binary input it returns a String note
- Wrap bytes() with a strict shim that raises ArgumentError when the bit count is not a multiple of 8
- Cover 1-, 7-, 8- and 9-bit inputs in tests so misalignment fails loudly in CI, not in production
When it happens
Trigger: bytes('0b101', 'binary') returns the note String (3 bits); bytes('0b101010101', 'binary') likewise (9 bits); chaining .map onto either result raises NoMethodError in the caller. Through the bundled CLIs, sha256.rb with a non-byte-aligned binary input actually ignores the bytes() return value (it uses input[2..-1] as the message directly), so the note mostly bites scripts that require sha256lib.rb and call bytes() themselves.
Common situations: Typing tutorial example bit strings one bit off (7 or 9 instead of 8); converting integers with to_s(2) and forgetting to pad to whole bytes; scripting against sha256lib.rb as a library and mapping over bytes() output unconditionally.
Related errors
- Invalid binary string: #{input}
- Invalid hex string: #{input}
- We only operate on 32-bit words in SHA-256. Your x is #{ARGV
- Invalid input to hash256.rb. Expecting even number of hex ch
AI-assisted analysis of in3rsha/sha256-animation@871e976d69 (2026-08-23).
Data as JSON: /api/errors/ea1faedfe002479a.
Report an issue: GitHub.