Jason Larsen wrote in post #949355:
> PROBLEM 1: I need to pad the message by appending a 1-bit, and then a
> certain number of 0s. When appending numbers (e.g. 0b1) to the end of
> by string, Ruby wraps each number in its Fixnum class making it 1 byte
> long: So basically adding 0b1 appends 0b0000_0001, which is 7 zeros
> that shouldn't be there. The fix I've found is I to tack 0x80 on the
> end, which concats 0b1000_0000. The downside is that I have to keep
> track of my zeros in batches of bytes (which at this point my
> implementation handles alright), but I'd like to know how to do it bit
> by bit if possible.

A String in ruby is a collection of bytes, not bits.

I think you'll find that as long as your input to your sha1 algorithm is 
also a String, and thus a multiple of 8 bits, everything will work fine.

The way the sha1 algorithm is defined it can be implemented for an input 
which is not a multiple of 8 bits, but as you've found, it's not easy to 
represent that anyway :-) Therefore, if you want your implementation to 
work with strange numbers of bits, you'll first need to choose an input 
representation.

If I were you, I'd be happy to limit my implementation to inputs which 
are whole bytes. (After all, even a file on the filesystem is a whole 
number of bytes)

> PROBLEM 2: After adding a one-bit and k zeros, I need to append a 64-
> bit long integer representing the length of the message being hashed.
> It seem like Fixnum is 8 bytes long on my machine, so the question is
> how do I add a 64bit binary representation of this number to the end
> of a string?

Don't worry about Fixnum versus Bignum, that's internal to the 
implementation and mostly hidden. Even on a 32-bit machine you can make 
Integers which are 64-bits and above.

Unfortunately, Array#pack("Q") works differently on little-endian and 
big-endian machines:

irb(main):001:0> [255].pack("Q")
=> "\377\000\000\000\000\000\000\000"

So for maximum portability I'd do two instances of "N", i.e.

>> n = 0x0123456789abcdef
=> 81985529216486895
>> [n >> 32, n].pack("NN")
=> "\001#Eg\211\253\315\357"

which you can check is correct like this:

>> [n >> 32, n].pack("NN").unpack("H*")
=> ["0123456789abcdef"]

Regards,

Brian.

-- 
Posted via http://www.ruby-forum.com/.