





'''simple docstring'''


import argparse
import hashlib  # hashlib is only used inside the Test class
import struct

class    lowerCAmelCase_		:




 def __init__(	self			,     _lowerCAmelCase		)    ->							Any:
     _lowerCAmelCase				=      data
     _lowerCAmelCase				=      [0X67_45_23_01, 0XEF_CD_AB_89, 0X98_BA_DC_FE, 0X10_32_54_76, 0XC3_D2_E1_F0]




 @staticmethod
 def 							_snake_case   (	_lowerCAmelCase			,     _lowerCAmelCase		)    ->							Tuple:
     return ((n << b) | (n >> (32 - b))) & 0XFF_FF_FF_FF




 def 							_snake_case   (	self		)    ->							Dict:
     _lowerCAmelCase				=      B"\x80" + B"\x00" * (63 - (len(self.data		) + 8) % 64)
     _lowerCAmelCase				=      self.data + padding + struct.pack(">Q"			,     8 * len(self.data		)		)
     return padded_data




 def 							_snake_case   (	self		)    ->							List[Any]:
     return [
         self.padded_data[i : i + 64] for i in range(0			,     len(self.padded_data		)			,     64		)
     ]




 def 							_snake_case   (	self			,     _lowerCAmelCase		)    ->							List[Any]:
     _lowerCAmelCase				=      list(struct.unpack(">16L"			,     _lowerCAmelCase		)		) + [0] * 64
     for i in range(16			,     80		):
         _lowerCAmelCase				=      self.rotate((w[i - 3] ^ w[i - 8] ^ w[i - 14] ^ w[i - 16])			,     1		)
     return w





 def 							_snake_case   (	self		)    ->							List[Any]:
     _lowerCAmelCase				=      self.padding()
     _lowerCAmelCase				=      self.split_blocks()
     for block in self.blocks:
         _lowerCAmelCase				=      self.expand_block(_lowerCAmelCase		)
         _lowerCAmelCase			,			_lowerCAmelCase			,			_lowerCAmelCase			,			_lowerCAmelCase			,			_lowerCAmelCase				=      self.h
         for i in range(0			,     80		):
             if 0 <= i < 20:
                 _lowerCAmelCase				=      (b & c) | ((~b) & d)
                 _lowerCAmelCase				=      0X5A_82_79_99
             elif 20 <= i < 40:
                 _lowerCAmelCase				=      b ^ c ^ d
                 _lowerCAmelCase				=      0X6E_D9_EB_A1
             elif 40 <= i < 60:
                 _lowerCAmelCase				=      (b & c) | (b & d) | (c & d)
                 _lowerCAmelCase				=      0X8F_1B_BC_DC
             elif 60 <= i < 80:
                 _lowerCAmelCase				=      b ^ c ^ d
                 _lowerCAmelCase				=      0XCA_62_C1_D6
             _lowerCAmelCase			,			_lowerCAmelCase			,			_lowerCAmelCase			,			_lowerCAmelCase			,			_lowerCAmelCase				=      (
                 self.rotate(_lowerCAmelCase			,     5		) + f + e + k + expanded_block[i] & 0XFF_FF_FF_FF,
                 a,
                 self.rotate(_lowerCAmelCase			,     30		),
                 c,
                 d,
             )
         _lowerCAmelCase				=      (
             self.h[0] + a & 0XFF_FF_FF_FF,
             self.h[1] + b & 0XFF_FF_FF_FF,
             self.h[2] + c & 0XFF_FF_FF_FF,
             self.h[3] + d & 0XFF_FF_FF_FF,
             self.h[4] + e & 0XFF_FF_FF_FF,
         )
     return ("{:08x}" * 5).format(*self.h		)







def 	__a():



    '''simple docstring'''





    _lowerCAmelCase				=      B"Test String"
    assert SHAaHash(SCREAMING_SNAKE_CASE_    ).final_hash() == hashlib.shaa(SCREAMING_SNAKE_CASE_    ).hexdigest()  # noqa: S324


def 	__a():



    '''simple docstring'''





    _lowerCAmelCase				=      argparse.ArgumentParser(description="Process some strings or files"    )
    parser.add_argument(
        "--string"		,       dest="input_string"		,       default="Hello World!! Welcome to Cryptography"		,       help="Hash the string"		,       )
    parser.add_argument("--file"		,       dest="input_file"		,       help="Hash contents of a file"    )
    _lowerCAmelCase				=      parser.parse_args()
    _lowerCAmelCase				=      args.input_string
    # In any case hash input should be a bytestring
    if args.input_file:
        with open(args.input_file		,       "rb"    ) as f:
            _lowerCAmelCase				=      f.read()
    else:
        _lowerCAmelCase				=      bytes(SCREAMING_SNAKE_CASE_		,       "utf-8"    )
    print(SHAaHash(SCREAMING_SNAKE_CASE_    ).final_hash()    )


if __name__ == "__main__":
       main()
       import doctest

       doctest.testmod()









'''simple docstring'''


_SCREAMING_SNAKE_CASE	 =							range(2, 20 + 1)
_SCREAMING_SNAKE_CASE	 =							[10**k for k in range(ks[-1] + 1)]
_SCREAMING_SNAKE_CASE	 =							{}


def 	__a(SCREAMING_SNAKE_CASE_  :					Tuple		,       SCREAMING_SNAKE_CASE_  :					str		,       SCREAMING_SNAKE_CASE_  :					Any		,       SCREAMING_SNAKE_CASE_  :					List[str]    ):



    '''simple docstring'''





    _lowerCAmelCase				=      sum(a_i[j] for j in range(SCREAMING_SNAKE_CASE_		,       len(SCREAMING_SNAKE_CASE_    )    )    )
    _lowerCAmelCase				=      sum(a_i[j] * base[j] for j in range(min(len(SCREAMING_SNAKE_CASE_    )		,       SCREAMING_SNAKE_CASE_    )    )    )

    _lowerCAmelCase			,			_lowerCAmelCase				=      0, 0
    _lowerCAmelCase				=      n - i

    _lowerCAmelCase				=      memo.get(SCREAMING_SNAKE_CASE_    )

    if sub_memo is not None:
        _lowerCAmelCase				=      sub_memo.get(SCREAMING_SNAKE_CASE_    )

        if jumps is not None and len(SCREAMING_SNAKE_CASE_    ) > 0:
            # find and make the largest jump without going over
            _lowerCAmelCase				=      -1
            for _k in range(len(SCREAMING_SNAKE_CASE_    ) - 1		,       -1		,       -1    ):
                if jumps[_k][2] <= k and jumps[_k][1] <= max_dn:
                    _lowerCAmelCase				=      _k
                    break

            if max_jump >= 0:
                _lowerCAmelCase			,			_lowerCAmelCase			,			_lowerCAmelCase				=      jumps[max_jump]
                # since the difference between jumps is cached, add c
                _lowerCAmelCase				=      diff + c
                for j in range(min(SCREAMING_SNAKE_CASE_		,       len(SCREAMING_SNAKE_CASE_    )    )    ):
                    _lowerCAmelCase			,			_lowerCAmelCase				=      divmod(SCREAMING_SNAKE_CASE_		,       10    )
                if new_c > 0:
                    add(SCREAMING_SNAKE_CASE_		,       SCREAMING_SNAKE_CASE_		,       SCREAMING_SNAKE_CASE_    )

        else:
            _lowerCAmelCase				=      []
    else:
        _lowerCAmelCase				=      {c: []}
        _lowerCAmelCase				=      sub_memo

    if dn >= max_dn or c + diff >= base[k]:
        return diff, dn

    if k > ks[0]:
        while True:
            # keep doing smaller jumps
            _lowerCAmelCase			,			_lowerCAmelCase				=      next_term(SCREAMING_SNAKE_CASE_		,       k - 1		,       i + dn		,       SCREAMING_SNAKE_CASE_    )
            diff += _diff
            dn += terms_jumped

            if dn >= max_dn or c + diff >= base[k]:
                break
    else:
        # would be too small a jump, just compute sequential terms instead
        _lowerCAmelCase			,			_lowerCAmelCase				=      compute(SCREAMING_SNAKE_CASE_		,       SCREAMING_SNAKE_CASE_		,       i + dn		,       SCREAMING_SNAKE_CASE_    )
        diff += _diff
        dn += terms_jumped

    _lowerCAmelCase				=      sub_memo[c]

    # keep jumps sorted by # of terms skipped
    _lowerCAmelCase				=      0
    while j < len(SCREAMING_SNAKE_CASE_    ):
        if jumps[j][1] > dn:
            break
        j += 1

    # cache the jump for this value digitsum(b) and c
    sub_memo[c].insert(SCREAMING_SNAKE_CASE_		,       (diff, dn, k)    )
    return (diff, dn)


def 	__a(SCREAMING_SNAKE_CASE_  :					Dict		,       SCREAMING_SNAKE_CASE_  :					int		,       SCREAMING_SNAKE_CASE_  :					Dict		,       SCREAMING_SNAKE_CASE_  :					Union[str, Any]    ):



    '''simple docstring'''





    if i >= n:
        return 0, i
    if k > len(SCREAMING_SNAKE_CASE_    ):
        a_i.extend([0 for _ in range(k - len(SCREAMING_SNAKE_CASE_    )    )]    )

    # note: a_i -> b * 10^k + c
    # ds_b -> digitsum(b)
    # ds_c -> digitsum(c)
    _lowerCAmelCase				=      i
    _lowerCAmelCase			,			_lowerCAmelCase			,			_lowerCAmelCase				=      0, 0, 0
    for j in range(len(SCREAMING_SNAKE_CASE_    )    ):
        if j >= k:
            ds_b += a_i[j]
        else:
            ds_c += a_i[j]

    while i < n:
        i += 1
        _lowerCAmelCase				=      ds_c + ds_b
        diff += addend
        _lowerCAmelCase				=      0
        for j in range(SCREAMING_SNAKE_CASE_    ):
            _lowerCAmelCase				=      a_i[j] + addend
            _lowerCAmelCase			,			_lowerCAmelCase				=      divmod(SCREAMING_SNAKE_CASE_		,       10    )

            ds_c += a_i[j]

        if addend > 0:
            break

    if addend > 0:
        add(SCREAMING_SNAKE_CASE_		,       SCREAMING_SNAKE_CASE_		,       SCREAMING_SNAKE_CASE_    )
    return diff, i - start_i


def 	__a(SCREAMING_SNAKE_CASE_  :					List[Any]		,       SCREAMING_SNAKE_CASE_  :					int		,       SCREAMING_SNAKE_CASE_  :					Any    ):



    '''simple docstring'''





    for j in range(SCREAMING_SNAKE_CASE_		,       len(SCREAMING_SNAKE_CASE_    )    ):
        _lowerCAmelCase				=      digits[j] + addend
        if s >= 10:
            _lowerCAmelCase			,			_lowerCAmelCase				=      divmod(SCREAMING_SNAKE_CASE_		,       10    )
            _lowerCAmelCase				=      addend // 10 + quotient
        else:
            _lowerCAmelCase				=      s
            _lowerCAmelCase				=      addend // 10

        if addend == 0:
            break

    while addend > 0:
        _lowerCAmelCase			,			_lowerCAmelCase				=      divmod(SCREAMING_SNAKE_CASE_		,       10    )
        digits.append(SCREAMING_SNAKE_CASE_    )


def 	__a(SCREAMING_SNAKE_CASE_  :					int = 10**15    ):



    '''simple docstring'''





    _lowerCAmelCase				=      [1]
    _lowerCAmelCase				=      1
    _lowerCAmelCase				=      0
    while True:
        _lowerCAmelCase			,			_lowerCAmelCase				=      next_term(SCREAMING_SNAKE_CASE_		,       20		,       i + dn		,       SCREAMING_SNAKE_CASE_    )
        dn += terms_jumped
        if dn == n - i:
            break

    _lowerCAmelCase				=      0
    for j in range(len(SCREAMING_SNAKE_CASE_    )    ):
        a_n += digits[j] * 10**j
    return a_n


if __name__ == "__main__":
       print(f'''{solution() = }''')


