k98kurz

difficulty.py_old

Jul 14th, 2021 (edited)
923
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 3.45 KB | None | 0 0
  1. from hashlib import new
  2. from sys import argv
  3.  
  4. '''
  5.    Copyleft (c) 2021 k98kurz
  6.  
  7.    Permission to use, copy, modify, and/or distribute this software for any
  8.    purpose with or without fee is hereby granted, provided that the above
  9.    copyleft notice and this permission notice appear in all copies.
  10.  
  11.    THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  12.    WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  13.    MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
  14.    SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  15.    WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
  16.    OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  17.    CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  18. '''
  19.  
  20. # returns the calculated difficulty
  21. def calculate(hash: bytes, bigendian: bool = True) -> int:
  22.     # prepare variables
  23.     number = int.from_bytes(hash, byteorder = 'big' if bigendian else 'little')
  24.     length = len(hash)
  25.     trailing_bits = 0
  26.  
  27.     # shift off bits until a null result is achieved
  28.     while number != 0 and trailing_bits < length * 8:
  29.         number = number >> 1
  30.         trailing_bits += 1
  31.  
  32.     # difficulty achieved is the preceeding null bits
  33.     return length * 8 - trailing_bits
  34.  
  35.  
  36. # checks if a hash has the correct difficulty (preceeding null bits)
  37. def check(diff: int, hash: bytes, bigendian: bool = True) -> bool:
  38.     # prepare variables
  39.     number = int.from_bytes(hash, byteorder='big' if bigendian else 'little')
  40.     length = len(hash)
  41.  
  42.     # raise exception if difficulty is impossible to achieve
  43.     if diff > length * 8:
  44.         raise Exception('Difficulty cannot exceed bit length of input')
  45.  
  46.     # shift off all but {diff} preceding bits
  47.     preceding_bits = number >> (length * 8 - diff)
  48.  
  49.     # it meets the difficulty if preceding bits are 0
  50.     return preceding_bits == 0
  51.  
  52.  
  53. # cli
  54. def main(args):
  55.     op = args[0].split(':')
  56.     mode = args[1].split(':')
  57.     input = args[2]
  58.     bigendian = True if len(args) < 4 else bool(args[3])
  59.  
  60.     if len(op) == 1:
  61.         # default op, e.g. calculate
  62.         if len(mode) == 1:
  63.             # default mode, e.g. no hashing
  64.             input = bytearray.fromhex(input) if mode[0] == 'hex' else bytes(input, 'utf-8')
  65.             print(calculate(input, bigendian))
  66.         else:
  67.             # hashing mode
  68.             input = new(mode[1], bytes(input, 'utf-8')).digest(len(input)) if 'shake' in mode[1] else new(mode[1], bytes(input, 'utf-8')).digest()
  69.             print(calculate(input, bigendian))
  70.     else:
  71.         # difficulty checking op
  72.         if len(mode) == 1:
  73.             # default mode, e.g. no hashing
  74.             input = bytearray.fromhex(input) if mode[0] == 'hex' else bytes(input, 'utf-8')
  75.             print('pass' if check(int(op[1]), input, bigendian) else 'fail')
  76.         else:
  77.             # hashing mode
  78.             input = new(mode[1], bytes(input, 'utf-8')).digest(len(input)) if 'shake' in mode[1] else new(mode[1], bytes(input, 'utf-8')).digest()
  79.             print('pass' if check(int(op[1]), input, bigendian) else 'fail')
  80.  
  81.  
  82. # cli
  83. if __name__ == '__main__':
  84.     if len(argv) < 4:
  85.         print('calculate difficulty of a given hash or check if it reaches a threshold')
  86.         print('usage: ' + argv[0] + ' [check:{number}|calc] [hash:{hashlib_algo}|hex|str] [utf-8 string] [bigendian=True]')
  87.         exit(1)
  88.     main(argv[1:])
  89.  
Add Comment
Please, Sign In to add comment