libbanana.py 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. """Main module."""
  2. import logging
  3. import random
  4. log = logging.getLogger("libbanana")
  5. class Codec:
  6. def __init__(self, shiftalpha=0, alphaend=0, minlength=0, alphabets=None):
  7. self.shiftalpha = shiftalpha
  8. self.alphaend = alphaend
  9. if alphabets is None:
  10. self.alphabets = [list("bcdfglmnprstvz"), list("aeiou")]
  11. else:
  12. self.alphabets = alphabets
  13. def encode(self, num, minlength=1):
  14. alphabets = self.alphabets
  15. numalpha = len(alphabets)
  16. v = num
  17. st = ""
  18. length = 0
  19. idx = (numalpha - 1 + self.shiftalpha + self.alphaend) % numalpha
  20. while not (
  21. v == 0
  22. and idx == (numalpha - 1 + self.shiftalpha) % numalpha
  23. and length >= minlength
  24. ):
  25. r = v % len(alphabets[idx])
  26. v = int(v / len(alphabets[idx]))
  27. st = alphabets[idx][r] + st
  28. idx = (idx - 1) % numalpha
  29. length += 1
  30. return st
  31. def decode(self, word):
  32. alphabets = self.alphabets
  33. numalpha = len(alphabets)
  34. if (len(word) - self.alphaend) % numalpha != 0:
  35. raise ValueError("Invalid banana")
  36. v = 0
  37. for i in range(len(word)):
  38. r = (numalpha + i + self.shiftalpha) % numalpha
  39. try:
  40. v = v * len(alphabets[r]) + alphabets[r].index(word[i])
  41. except (ValueError, KeyError):
  42. raise ValueError("Invalid character in position %d" % i + 1)
  43. return v
  44. def is_valid(self, word):
  45. alphabets = self.alphabets
  46. numalpha = len(alphabets)
  47. if (len(word) - self.alphaend) % numalpha != 0:
  48. return False
  49. for i in range(len(word)):
  50. r = (numalpha + i + self.shiftalpha) % numalpha
  51. if word[i] not in alphabets[r]:
  52. return False
  53. return True
  54. def random(self, minlength=6, prng=random.Random()):
  55. numalpha = len(self.alphabets)
  56. word = ""
  57. if minlength < 1:
  58. return ""
  59. curr_alpha = (numalpha - 1 + self.shiftalpha + self.alphaend) % numalpha
  60. final_alpha = (numalpha - 1 + self.shiftalpha) % numalpha
  61. while curr_alpha != final_alpha or len(word) < minlength:
  62. word = prng.choice(self.alphabets[curr_alpha]) + word
  63. curr_alpha = (curr_alpha - 1) % numalpha
  64. return word
  65. class BananaCodec(Codec):
  66. def __init__(self):
  67. super().__init__()
  68. if __name__ == "__main__":
  69. print("Hi I'm the basebanana library")