Ruby hash generate?

For general discussion related FlowStone
Post Reply
adamszabo
Posts: 667
Joined: Sun Jul 11, 2010 7:21 am

Ruby hash generate?

Post by adamszabo »

Hi everyone!

I am wondering if it possible to create a hash for an input string with Ruby? I am especially interested in the short ones like adler32, crc32 or joaat. I wrote in the word "Hello" and it gave me a lot of different hash types:

adler32: 062c0215
crc32: 3d653119
joaat: c8fd181b

Here are the results: https://md5hashing.net/hash/joaat/c8fd181b

I have been searching for some help online and all the ruby codes seem to use some Zlib, which I dont even have a clue what that is. Does any one have any expertise in this field? :)
tulamide
Posts: 2714
Joined: Sat Jun 21, 2014 2:48 pm
Location: Germany

Re: Ruby hash generate?

Post by tulamide »

As much as I would love to help, Ruby forbid it. I had a look at the original code for Jenkins one-at-a-time (Joaat). The code is quite simple and it wasn't very difficult to convert it to Ruby.

However, the original code takes advantage of overflow. Here's an example. Say, I have a 4 bit number

Code: Select all

a = 0b0001 # 1 as bitsequence
a = a << 3 # all bits shifted to the right 3 times = 0b1000 or 8

## Now what happens if we shift 4 times?
a = 0b0001 # 1 as bitsequence
a = a << 4 # all bits shifted to the right 4 times = 0b10000 or 16


In C++ this wouldn't be possible, because the number is defined as 4 bits. The 5th bit overflowed. It is just truncated and the result would be

Code: Select all

a = a << 4 # all bits shifted to the right 4 times and truncated = 0b0000 or 0


The Joaat code uses this behaviour to its advantage several times. Unfortunately, Ruby only knows to types of integer numbers, fixnum and bignum. Fixnum is based on the system (32 or 64 bits). As soon as the number exceeds the allowed number of bits it is automatically converted to a bignum, which is basically endless.

I don't know how to prevent that. But, since I have hope that Myco will have a cool idea, here's the code tranlated 1:1, meaning it isn't working yet:

Code: Select all

#uint32_t jenkins_one_at_a_time_hash(char *key, size_t len)
#{
#    uint32_t hash, i;
#    for(hash = i = 0; i < len; ++i)
#    {
#        hash += key[i];
#        hash += (hash << 10);
#        hash ^= (hash >> 6);
#    }
#    hash += (hash << 3);
#    hash ^= (hash >> 11);
#    hash += (hash << 15);
#    return hash;
#}

def joaat(key)
   hash = 0
   key.each_byte do |c|
      hash += c
      hash += (hash << 10)
      hash = hash ^ (hash >> 6)   
   end
   hash += (hash << 3)
   hash = hash ^ (hash >> 11)
   hash += (hash << 15)
   return hash
end

joaat("hello").to_s(16)


I hope the 32bit truncation will be possible somehow and the sign bit used as number bit. Then it will work. Come on, you programmers :)
"There lies the dog buried" (German saying translated literally)
KG_is_back
Posts: 1196
Joined: Tue Oct 22, 2013 5:43 pm
Location: Slovakia

Re: Ruby hash generate?

Post by KG_is_back »

You may possibly use logical bitwise AND.

Code: Select all

def overflow(n,bitdeapth)
n & (2**bitdeapth -1)
end


It will output an unsigned integer only... I might have to think more deeply about it to make it work with signed...
tulamide
Posts: 2714
Joined: Sat Jun 21, 2014 2:48 pm
Location: Germany

Re: Ruby hash generate?

Post by tulamide »

Yes, please think it over, maybe you'll have an idea.
I also thought about bitmasking. The thing is, it just works one way (for shifting <<). Again a 4bit example:

Code: Select all

a = 0b1001 # number 9
a = a >> 2 # a will be 0b001001 or 9
a = a & 15 # bitmasking  over 4 bit length, a will still be 0b1001


In C++ a would be 0b0010 = 2 instead
"There lies the dog buried" (German saying translated literally)
KG_is_back
Posts: 1196
Joined: Tue Oct 22, 2013 5:43 pm
Location: Slovakia

Re: Ruby hash generate?

Post by KG_is_back »

I think you are wrong about the bitmasking (at least my experimentation confirms your're wrong). ">>" actually denotes LOGICAL right bitshift. That means digits are shifted right, the ones missing on the left get zero and the ones that "overflow" on the right are forever lost.

Code: Select all

a=0b1001 =9
a= a >> 2 #gives 0b10 = 2
a = a << 2 #gives 0b1000 = 8


also I think I have a solution to the problem:

Code: Select all

def overflow(n,bitsize)
n=n & (2**bitsize - 1)
n= (n>= 2**(bitsize-1)) ? n-(2**(bitsize)) : n
end


this little method will give you overflow result represented as a SIGNED integer. to get an unsigned result, just comment the last line...
tulamide
Posts: 2714
Joined: Sat Jun 21, 2014 2:48 pm
Location: Germany

Re: Ruby hash generate?

Post by tulamide »

Now that is cool!

I admit, I didn't test what I thought would happen, so thanks a lot for taking the time to test Ruby. Now I'll integrate the overflow method (probably tomorrow, to late tonight). I'm afraid it needs to be called after each shift, but speed hopefully is not of interest, at least not for a first working version.
"There lies the dog buried" (German saying translated literally)
tulamide
Posts: 2714
Joined: Sat Jun 21, 2014 2:48 pm
Location: Germany

Re: Ruby hash generate?

Post by tulamide »

Simple Joaat Hash Generator

Whenever the string input is changed a hash is generated.

Many thanks to KG for his bitmasking idea. It turned out that unsigned works correctly.
Attachments
JOAAT.fsm
(763 Bytes) Downloaded 847 times
"There lies the dog buried" (German saying translated literally)
adamszabo
Posts: 667
Joined: Sun Jul 11, 2010 7:21 am

Re: Ruby hash generate?

Post by adamszabo »

Very cool guys! Im still trying to understand how it works :) Can this code do a reverse as well? So I write the hash and outputs the original string?
KG_is_back
Posts: 1196
Joined: Tue Oct 22, 2013 5:43 pm
Location: Slovakia

Re: Ruby hash generate?

Post by KG_is_back »

adamszabo wrote:Very cool guys! Im still trying to understand how it works :) Can this code do a reverse as well? So I write the hash and outputs the original string?


I believe that is not possible. The whole idea of hashing is, that from a big string (or a file) you generate small short hash (a text or a number). The hash is however usually not unique (there may and most likely are strings with the same hash), though it is very hard to find two different strings with the same hash. They are mainly used to verify if given file is original (if the file was modified, it will generate different hash). The process is not reversible - the hash generation is a destructive process.
tulamide
Posts: 2714
Joined: Sat Jun 21, 2014 2:48 pm
Location: Germany

Re: Ruby hash generate?

Post by tulamide »

What KG said. If you followed this thread you might have noticed that I talked of truncating. At least then it will not be reversible, since information is lost. I don't know if there are hash algorithms that are non-destructive, but Joaat is destructive for sure. If you see some kind of de-hashing somewhere it is most probably a huge library of known source/hash relationships that are just looked up.
"There lies the dog buried" (German saying translated literally)
Post Reply