root/dotorg/trunk/html/beps/bep_0008.py

Revision 10851, 2.1 KB (checked in by dave, 2 years ago)

Fix in example python that causes incorrect results when returned peer
list wraps end of tracker peer list.

Line 
1from sha import sha
2from random import randint
3from struct import unpack
4#from rc4 import rc4              # generates RC4 psuedorandom string.
5
6rand = open("/dev/random","r").read
7
8class RC4:
9  def __call__(self, i):
10    return rand(i)
11
12rc4 = RC4()                       # replace with actual RC4 implementation.
13
14# tracker configuration
15MAX_PEERS = 100
16
17# per torrent state.
18infohash = sha("dummy_info").digest()
19pseudo = ''                        # pseudorandom RC-4 string.
20num_peers = 1000                   # current swarm size.
21tracker_peer_list = rand(6) * num_peers
22obfuscated_tracker_peer_list = '' 
23
24def xor(plaintext,pseudo):
25  isint = False
26  if type(plaintext) == int: # convert to byte string.
27    plaintext = "".join([chr(int(x,16)) for x in "%.4x" % plaintext])
28    isint = True
29
30  n = len(pseudo)
31   
32  ciphertext = "".join(
33    [chr(ord(pseudo[i%n])^ord(plaintext[i])) for i in xrange(len(plaintext))] )
34
35  if isint:
36    ciphertext = unpack("!I", ciphertext)[0]   # convert back to unsigned int
37  return ciphertext
38
39def init():  # called once per rerequest interval.
40  global iv, x, n, n_xor_y, obfuscated_tracker_peer_list
41  iv = rand(20)
42  rc4.key = sha(infohash + iv).digest()[0:8]
43  rc4(768)                         # discard first 768
44  x = rc4(4)
45  y = rc4(4)
46  n = min(num_peers, randint(MAX_PEERS * 2, MAX_PEERS * 4))
47  n_xor_y = xor(n,y)
48  pseudo = rc4(n*6)
49  obfuscated_tracker_peer_list = xor(tracker_peer_list,pseudo)
50
51def getpeers( numwant ):
52  global iv, x, n, n_xor_y, obfuscated_tracker_peer_list
53  response = {}
54  response['iv'] = iv
55  numwant = min(numwant, MAX_PEERS)
56  if numwant >= num_peers:
57    response['peers'] = obfuscated_tracker_peer_list
58    return response
59
60  i = randint(0,num_peers-numwant)
61  response['i'] = xor(i,x)
62  response['n'] = n_xor_y
63  # peers at end of tracker peer list have lower probability of being picked,
64  # but this requires only one copy.
65  response['peers'] = obfuscated_tracker_peer_list[i*6:(i+numwant)*6] 
66  return response
67
68init()
69response = getpeers(20)
70print "response=", response
71print "len(response['peers'])=", len(response['peers'])
Note: See TracBrowser for help on using the browser.