#/*
# **********************************************************************
# ** MD.py Source file for stream cipher based hash                   **
# ** Franz Scherer Software  Perfect Stream Cipher based Hash         **
# ** Created: 09/04/2016                                              **
# **********************************************************************
# */

#/*
# **********************************************************************
# ** Copyright (C) 2016, Scheerer Software, All rights reserved.      **
# **                                                                  **
# ** License to copy and use this software is granted provided that   **
# ** it is identified as the "Franz Scheerer Software, Perfect Stream **
# ** Cipher based Hash Algorithm" in all material mentioning or       ** 
# ** referencing this software or this function.                      **
# **                                                                  **
# ** License is also granted to make and use derivative works         **
# ** provided that such works are identified as "derived from         **
# ** Franz Scheerer Software Perfect Stream Cipher Algorithm" in all  **
# ** material mentioning or referencing the derived work.             **
# **                                                                  **
# ** Franz Scheerer Software makes no representations concerning      **
# ** either the merchantability of this software or the suitability   **
# ** of this software for any particular purpose.  It is provided "as **
# ** is" without express or implied warranty of any kind.             **
# **                                                                  **
# ** These notices must be retained in any copies of any part of this **
# ** documentation and/or software.                                   **
# **********************************************************************
# */


def h(x):
  hx = '0123456789ABCDEF'
  ja = jb = jc = jd =je = jf = jg = jh = 0
  s = range(512)
  for i in range(512):
    s[i] = (i + 1) % 512
  i = 0
  for c in x: 
    for r in range(4): 
       i = (i + 1) % 512
       ja = (jh + s[(ja + s[i]) % 512]) % 512;
       jb = (jb + s[ja]) % 512
       jc = (jc + s[jb]) % 512
       jd = (jd + s[jc]) % 512
       je = (je + s[jd]) % 512
       jf = (jf + s[je]) % 512
       jg = (jg + s[jf]) % 512
       jh = (jh + s[jg]) % 512
       s[jc], s[i] = s[i], s[jc];
       if r==1: 
         ja = (ja + (ord(c) ^ s[i])) % 512
       else:
         ja = (ja ^ (ord(c) ^ s[i])) % 512
    
  for c in range(512):
     i = (i + 1) % 512
     jb = s[(jb + s[i]) % 512]
     s[i],s[jb] =  s[jb],s[i]
  out = ''
  for c in range(32):
    i = (i + 1) % 512
    ja = (ja + s[i]) % 512
    jb = (jb + s[ja]) % 512
    jc = (jc + s[jb]) % 512
    jd = (jc + s[jc]) % 512
    je = (jc + s[jd]) % 512
    jf = (jc + s[je]) % 512
    jg = (jc + s[jf]) % 512
    jh = (jh + s[jg]) % 512
    s[i],s[jh] =  s[jh],s[i]    
    out = out +  (hx[((s[i]>>4) & 0xF)] + hx[(s[i] & 0xF)])
  return out


