1
0

bencode.py 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. # The contents of this file are subject to the BitTorrent Open Source License
  2. # Version 1.1 (the License). You may not copy or use this file, in either
  3. # source code or executable form, except in compliance with the License. You
  4. # may obtain a copy of the License at http://www.bittorrent.com/license/.
  5. #
  6. # Software distributed under the License is distributed on an AS IS basis,
  7. # WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  8. # for the specific language governing rights and limitations under the
  9. # License.
  10. # Written by Petru Paler
  11. from BTL import BTFailure
  12. def decode_int(x, f):
  13. f += 1
  14. newf = x.index('e', f)
  15. n = int(x[f:newf])
  16. if x[f] == '-':
  17. if x[f + 1] == '0':
  18. raise ValueError
  19. elif x[f] == '0' and newf != f+1:
  20. raise ValueError
  21. return (n, newf+1)
  22. def decode_string(x, f):
  23. colon = x.index(':', f)
  24. n = int(x[f:colon])
  25. if x[f] == '0' and colon != f+1:
  26. raise ValueError
  27. colon += 1
  28. return (x[colon:colon+n], colon+n)
  29. def decode_list(x, f):
  30. r, f = [], f+1
  31. while x[f] != 'e':
  32. v, f = decode_func[x[f]](x, f)
  33. r.append(v)
  34. return (r, f + 1)
  35. def decode_dict(x, f):
  36. r, f = {}, f+1
  37. while x[f] != 'e':
  38. k, f = decode_string(x, f)
  39. r[k], f = decode_func[x[f]](x, f)
  40. return (r, f + 1)
  41. decode_func = {}
  42. decode_func['l'] = decode_list
  43. decode_func['d'] = decode_dict
  44. decode_func['i'] = decode_int
  45. decode_func['0'] = decode_string
  46. decode_func['1'] = decode_string
  47. decode_func['2'] = decode_string
  48. decode_func['3'] = decode_string
  49. decode_func['4'] = decode_string
  50. decode_func['5'] = decode_string
  51. decode_func['6'] = decode_string
  52. decode_func['7'] = decode_string
  53. decode_func['8'] = decode_string
  54. decode_func['9'] = decode_string
  55. def bdecode(x):
  56. try:
  57. r, l = decode_func[x[0]](x, 0)
  58. except (IndexError, KeyError, ValueError):
  59. raise BTFailure("not a valid bencoded string")
  60. if l != len(x):
  61. raise BTFailure("invalid bencoded value (data after valid prefix)")
  62. return r
  63. from types import StringType, IntType, LongType, DictType, ListType, TupleType
  64. class Bencached(object):
  65. __slots__ = ['bencoded']
  66. def __init__(self, s):
  67. self.bencoded = s
  68. def encode_bencached(x,r):
  69. r.append(x.bencoded)
  70. def encode_int(x, r):
  71. r.extend(('i', str(x), 'e'))
  72. def encode_bool(x, r):
  73. if x:
  74. encode_int(1, r)
  75. else:
  76. encode_int(0, r)
  77. def encode_string(x, r):
  78. r.extend((str(len(x)), ':', x))
  79. def encode_list(x, r):
  80. r.append('l')
  81. for i in x:
  82. encode_func[type(i)](i, r)
  83. r.append('e')
  84. def encode_dict(x,r):
  85. r.append('d')
  86. ilist = x.items()
  87. ilist.sort()
  88. for k, v in ilist:
  89. r.extend((str(len(k)), ':', k))
  90. encode_func[type(v)](v, r)
  91. r.append('e')
  92. encode_func = {}
  93. encode_func[Bencached] = encode_bencached
  94. encode_func[IntType] = encode_int
  95. encode_func[LongType] = encode_int
  96. encode_func[StringType] = encode_string
  97. encode_func[ListType] = encode_list
  98. encode_func[TupleType] = encode_list
  99. encode_func[DictType] = encode_dict
  100. try:
  101. from types import BooleanType
  102. encode_func[BooleanType] = encode_bool
  103. except ImportError:
  104. pass
  105. def bencode(x):
  106. r = []
  107. encode_func[type(x)](x, r)
  108. return ''.join(r)