# I really give up

QnickQm at alum.mit.edu QnickQm at alum.mit.edu
Wed Oct 2 17:56:17 CEST 2002

```In article <anf1bj\$vu\$1 at news.tpi.pl>, piter wrote:
> Hey guys,
>
> I really give up! How to convert the following C function into python?
>
> //-----------------------------------------
> unsigned int
> make_hash(char *password, unsigned int seed)
> {
>     unsigned int x, y, z;
>
>     y = seed;
>
>     for (x = 0; *password; password++) {
>         x = (x & 0xffffff00) | *password;
>         y ^= x;
>         y += x;
>         x <<= 8;
>         y ^= x;
>         x <<= 8;
>         y -= x;
>         x <<= 8;
>         y ^= x;
>
>         z = y & 0x1f;
>         y = (y << z) | (y >> (32 - z));
>     }
>
>     return y;
> }
>
> //-----------------------------------------
>
> The obvious solution:
[...]
> produces odd result due to python's signed arithmetic.

One solution: use the low-order bytes of Python's long integers.

def make_hash(password, seed):
y = long(seed)
x = 0L
for ch in password:
x = (x & 0xffffff00L) | ord(ch)
y ^= x
y += x
x <<= 8
y ^= x
x <<= 8
y -= x
x <<= 8
y ^= x
z = int(y & 0x1f)
y &= 0xffffffffL
y = ((y << z) | ((y >> (32- z))))

return y & 0xffffffffL

Note however that this hashing algorithm is *not* secure.  A decent desktop
takes less than 4 minutes to try 2**32 passwords with a given seed.  Thus,
assuming that the hashing algorithm works, I can should be able to find
a password that hashes to any desired hash value for a given seed in that
amount of time.  You may as well store the passwords in plaintext.

Instead, may I suggest the sha module?

Avoiding-roll-your-own-crypto-like-the-plague-ly y'rs,

--
Nick Mathewson    <Q nick Q m at alum dot mit dot edu>
Remove Q's to respond.  No spam.

```

More information about the Python-list mailing list