Why does this return 255 bits instead of 256 (and general bit byte hex string array crypt mayhem :P)

So I am doing something that requires me to manipulate things on the bit
level, and am having a bit of a headache with learning to use pack and
unpack to accomplish my goal. I thought I came one step closer with
this, but was disappointed to see it thinks the result is 255 bits since
I think it should be 256. What gives?

hash = OpenSSL::Digest::SHA256.new
test_hash_value = hash << “anything”
puts test_hash_value.to_s.to_i(16).to_s(2).length

=> 255

shouldn’t it be 256? What is a better way to get the binary
representation of my hash string? I also note that

test_hash_value.to_s.unpack(‘B*’)[0]

has 512 as its length, I think this must be because it is hex but being
treated as a byte string so its * 16 instead of * 8 ?

I am really new to this stuff an having somewhat of a hard time going
between all of these formats so I will appreciate any help or if anyone
can point me to resources even.

The primary problem I am having is that I can get a binary
representation of various components, and then I need to concatenate
them and encrypt them together, but I need openssl to treat them as bits
and it is treating it as bytes if I do this:

string_to_encrypt = hash_string.to_s.unpack(‘B*’)[0] +
hash_string.to_s.unpack(‘B*’)[0] + ("\0" * 160).unpack(‘B*’)

I can see each of the components as a string of binary but then when I
encrypt string_to_encrypt with openSSL it seems to be treating it not as
a string of binary but as a normal string, judging by the very large
output size.

So my two goals are to get an accurate binary representation of hash
values, and to perform encryption operations on a bit string. I think I
am close to the first thing but I can only get 255 bits.

Even just some hints are greatly appreciated, I want to figure it out
myself but am starting to get frustrated with it :confused:

woot solved getting the binary string representation with this:

puts OpenSSL::BN.new(test_hash_value.to_s,
16).to_s(2).unpack(“B*”)[0].length

=> 256

I got 256 when running your code. It will always be 256 because of the
hash
you’re using but I’m guessing you have some other use for this.

I should also say that instead of those painful manipulations you could
simply multiply the length of the hash by eight.

The goal is to simplify, not complicate.

#begin
require ‘openssl’

hasher = OpenSSL::Digest::SHA256.new
test_hash = hasher << “something”

puts test_hash.length * 8

#end

On Fri, Apr 27, 2012 at 12:21 PM, instance_variable ok
<[email protected]

Yes but unfortunately I need the bit string, I was only getting its
length to make sure it was correct. Strange that you get 256 for the
first example, it tells me 255 if I do it this way:

puts test_hash_value.to_s.to_i(16).to_s(2).length

but 256 if I do it this way:

puts OpenSSL::BN.new(test_hash_value.to_s,
16).to_s(2).unpack(“B*”)[0].length

I agree that it is painful but I can’t find a better way :confused: at least it
works

On Sat, 2012-04-28 at 01:05 +0900, instance_variable ok wrote:

=> 255

shouldn’t it be 256? What is a better way to get the binary
representation of my hash string? I also note that

[12:58:04] rthompso@raker2>~
$ irb
irb(main):001:0> require ‘openssl’
=> true
irb(main):002:0> require ‘digest/sha2’
=> true
irb(main):003:0> hash = OpenSSL::Digest::SHA256.new
=> #<OpenSSL::Digest::SHA256:
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855>
irb(main):004:0> test_hash_value = hash << “anything”
=> #<OpenSSL::Digest::SHA256:
ee0874170b7f6f32b8c2ac9573c428d35b575270a66b757c2c0185d2bd09718d>
irb(main):005:0> p test_hash_value
#<OpenSSL::Digest::SHA256:
ee0874170b7f6f32b8c2ac9573c428d35b575270a66b757c2c0185d2bd09718d>
=> nil
irb(main):006:0> puts test_hash_value.to_s.to_i(16).to_s(2).length
256
=> nil
irb(main):007:0>

On Sat, 2012-04-28 at 03:10 +0900, instance_variable ok wrote:

test_hash_value = hash << “anything”
puts test_hash_value.length

it says 64 instead of 32 (*8 should = 256 but is equal to 512?)

Is it because of something to do with hex?

what os are you on

$ irb
irb(main):001:0> require ‘openssl’
=> true
irb(main):002:0> require ‘digest/sha2’
=> true
irb(main):003:0> hash = OpenSSL::Digest::SHA256.new
=> #<OpenSSL::Digest::SHA256:
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855>
irb(main):004:0> test_hash_value = hash << “anything”
=> #<OpenSSL::Digest::SHA256:
ee0874170b7f6f32b8c2ac9573c428d35b575270a66b757c2c0185d2bd09718d>
irb(main):005:0> puts test_hash_value.length
32
=> nil
irb(main):006:0>

Huh from IRB it shows 256 when I just went through it like you did, but
I know for sure earlier in my program it was saying 255 because it was
driving me crazy why it wasn’t 256. I must have done it differently or
something. Anyway thanks!

I have one more question and then will leave you all alone :stuck_out_tongue:

why is it if I do this

hash = OpenSSL::Digest::SHA256.new
test_hash_value = hash << “anything”
puts test_hash_value.length

it says 64 instead of 32 (*8 should = 256 but is equal to 512?)

Is it because of something to do with hex?

You’re asking for the length of two different things, one is an
OpenSSL::Digest::SHA256 object the other is a 32 character long string.

On Fri, Apr 27, 2012 at 4:36 PM, instance_variable ok

Sorry this was a mistake on my part, I meant this:

hash = OpenSSL::Digest::SHA256.new
test_hash_value = hash << “anything”
puts test_hash_value.to_s.length

if I don’t convert .to_s I get 32 as the length

I am on ubuntu

why does a 32 character long string have a length (and bytesize) of 64
is my question then…shouldn’t it be 8 * 32 = 256 bit hash ? I thought
every character was one byte

Sorry, I misspoke, I meant a 64 character string. The hash is 64
hexadecimal characters long.

On Fri, Apr 27, 2012 at 5:15 PM, instance_variable ok

Remember, when you convert an integer to a string (#to_s) that leading
zeros are trimmed off. So if a 256-bit hash happens to be an integer
that, when converted to a binary string representation, that string
may be from 1 to 256. If the hash was the integer zero (possible,
though unlikely), the length would be 1.

That may explain your results IF your hash input to SHA-256 was
something other than “anything” (which hash, since the the highest bit
at position 256 is a one, should produce a length of 256 when #to_s(2)
is called).

Aaron out.

Aaron D. Gifford wrote in post #1058735:

Example of #to_s “eating” leading zeros:

Of course it does, because it can’t guess how many leading zeros you
want:

5.to_s(2)
=> “101”

7.to_s(2)
=> “111”

14.to_s(2)
=> “1110”

17.to_s(2)
=> “10001”

If you want to tell it the number of digits, I suggest you use the %b
format convertor. e.g. to force 32 bits:

“%0.32b” % 17
=> “00000000000000000000000000010001”

However I question why you want to do this. You say you want to “get a
binary
representation of various components, and then I need to concatenate
them and encrypt them together,”

By “binary representation” I’m pretty sure you don’t really mean “ASCII
‘0’ followed by ASCII ‘1’ followed by ASCII ‘0’ …”

The data you have already is binary, and you can just concatenate it
and encrypt it. Converting it to text symbols is unlikely to achieve
what you want.

Example of #to_s “eating” leading zeros:

rb(main):001:0> require ‘digest/sha2’
=> true
irb(main):002:0> d = Digest::SHA256.hexdigest(3.chr+229.chr+245.chr)
=> “00000e302c2fd880c1615ce3104289c8fc142b30e10963d4a32fe7371e0f36b7”
irb(main):003:0> i = d.to_i(16)
=>
97923179718509917028425247791037714012132138545410096732043674779596471
irb(main):004:0> b = i.to_s(2)
=>
“11100011000000101100001011111101100010000000110000010110000101011100111000110001000001000010100010011100100011111100000101000010101100110000111000010000100101100011110101001010001100101111111001110011011100011110000011110011011010110111”
irb(main):005:0> b.length
=> 236

Note also:

irb(main):006:0> i.to_s.length
=> 71

…That #to_s does not include the leading zeros we expect because we
know that we started with a 256-bit hash.

Aaron out.