def _parse_7_string(cls, suffix): # XXX: annoyingly, official spec embeds salt *raw*, yet doesn't specify a hash encoding. # so assuming only h64 chars are valid for salt, and are ASCII encoded. # split into params & digest parts = suffix.encode("ascii").split(b"$") if len(parts) == 2: params, digest = parts elif len(parts) == 1: params, = parts digest = None else: raise uh.exc.MalformedHashError() # parse params & return if len(params) < 11: raise uh.exc.MalformedHashError(cls, "params field too short") return dict( ident=IDENT_7, rounds=h64.decode_int6(params[:1]), block_size=h64.decode_int30(params[1:6]), parallelism=h64.decode_int30(params[6:11]), salt=params[11:], checksum=h64.decode_bytes(digest) if digest else None, )
def from_string(cls, hash): ident, data = cls._parse_ident(hash) rounds, salt, chk = data[0], data[1:9], data[9:] return cls( ident=ident, rounds=h64.decode_int6(rounds.encode("ascii")), salt=salt, checksum=chk or None, )
def from_string(cls, hash): hash = to_unicode(hash, "ascii", "hash") ident, data = hash[0:3], hash[3:] if ident != cls.ident: raise exc.InvalidHashError() rounds, salt, chk = data[0], data[1:9], data[9:] return cls( rounds=h64.decode_int6(rounds.encode("ascii")), salt=salt, checksum=chk or None, )