/
util.py
101 lines (67 loc) · 2.38 KB
/
util.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
import os
import bencodepy
import hashlib
import socket
import math
from urllib.parse import urlparse
torrent_id = None
BLOCK_LENGTH = int(math.pow(2, 14))
def gen_id():
global torrent_id
if not torrent_id:
torrent_id = '-DM0001-'
torrent_id = torrent_id.encode() + os.urandom(20-len(torrent_id))
return torrent_id
def get_info_hash(torrent):
info = bencodepy.encode(torrent[b'info'])
hexdigest = hashlib.sha1(info).hexdigest()
info_hash = bytes.fromhex(hexdigest)
return info_hash
def get_torrent_length(torrent):
if b'files' in torrent[b'info']:
size = 0
for file_ in torrent[b'info'][b'files']:
size += file_[b'length']
else:
size = torrent[b'info'][b'length']
return (size).to_bytes(8, 'big')
def get_number_of_pieces(torrent):
return int(len(torrent[b'info'][b'pieces']) // 20)
def get_udp_tracker(torrent):
if b'announce-list' in torrent:
url_lists = torrent[b'announce-list']
for li in url_lists:
for item in li:
url = urlparse(item.decode())
if url.scheme=='udp':
try:
socket.gethostbyname(url.hostname)
return url
except socket.error:
pass
else:
url = urlparse(torrent[b'announce'].decode())
if url.scheme=='udp':
return url
return None
def piece_len(torrent, piece_index):
total_length = int(get_torrent_length(torrent).hex(), 16)
piece_length = torrent[b'info'][b'piece length']
last_piece_length = total_length % piece_length
last_piece_index = math.floor(total_length/piece_length)
return last_piece_length if last_piece_index==piece_index else piece_length
def blocks_per_piece(torrent, piece_index):
piece_length = piece_len(torrent, piece_index)
return math.ceil(piece_length/BLOCK_LENGTH)
def block_len(torrent, piece_index, block_index):
piece_length = piece_len(torrent, piece_index)
last_block_length = piece_length % BLOCK_LENGTH
last_block_index = math.floor(piece_length/BLOCK_LENGTH)
return last_block_length if last_block_index==block_index else BLOCK_LENGTH
def get_bits(hex_val):
int_val = int(hex_val, 16)
ret = ''
while int_val>0:
ret = str(int_val%2) + ret
int_val = int(int_val//2)
return ret