Add week 7 materials
This commit is contained in:
@@ -0,0 +1,73 @@
|
||||
"""Inspect a torrent or demonstrate unchanged infohash and damaged piece detection."""
|
||||
import argparse
|
||||
import json
|
||||
from pathlib import Path
|
||||
import sys
|
||||
from metainfo import decode, encode, inspect, make_metainfo, verify
|
||||
|
||||
|
||||
def describe(raw):
|
||||
meta, infohash = inspect(raw)
|
||||
info = meta[b"info"]
|
||||
print(json.dumps({
|
||||
"announce": meta[b"announce"].decode(),
|
||||
"name": info[b"name"].decode(),
|
||||
"length": info[b"length"],
|
||||
"piece length": info[b"piece length"],
|
||||
"pieces (SHA-1)": [info[b"pieces"][i:i + 20].hex()
|
||||
for i in range(0, len(info[b"pieces"]), 20)],
|
||||
"infohash (raw bencoded info)": infohash,
|
||||
}, indent=2))
|
||||
|
||||
|
||||
def demo(directory):
|
||||
directory.mkdir(parents=True, exist_ok=True)
|
||||
data = bytes(range(256)) * 1024
|
||||
original = encode(make_metainfo("lesson.bin", data))
|
||||
meta, original_info = decode(original)
|
||||
changed = dict(meta)
|
||||
changed[b"announce"] = b"http://127.0.0.1:6970/announce"
|
||||
changed[b"comment"] = b"A different comment"
|
||||
modified = encode(changed)
|
||||
assert decode(modified)[1] == original_info
|
||||
damaged = bytearray(data)
|
||||
damaged[65536 + 17] ^= 1
|
||||
for name, content in [("lesson.bin", data), ("lesson.torrent", original),
|
||||
("changed.torrent", modified), ("damaged.bin", damaged)]:
|
||||
(directory / name).write_bytes(content)
|
||||
describe(original)
|
||||
print("Original infohash:", inspect(original)[1])
|
||||
print("Changed infohash:", inspect(modified)[1])
|
||||
assert inspect(original)[1] == inspect(modified)[1]
|
||||
good, _ = verify(original, data)
|
||||
bad, indices = verify(original, damaged)
|
||||
assert good and not bad and indices == [1]
|
||||
print("PASS: changing announce/comment preserved infohash")
|
||||
print("PASS: original file verified; damaged file rejected, piece index:", indices)
|
||||
print("Files:", directory)
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
subs = parser.add_subparsers(dest="command", required=True)
|
||||
p = subs.add_parser("demo")
|
||||
p.add_argument("--directory", type=Path, default=Path(".local/metadata"))
|
||||
p = subs.add_parser("inspect")
|
||||
p.add_argument("torrent", type=Path)
|
||||
p = subs.add_parser("verify")
|
||||
p.add_argument("torrent", type=Path)
|
||||
p.add_argument("file", type=Path)
|
||||
args = parser.parse_args()
|
||||
if args.command == "demo":
|
||||
demo(args.directory)
|
||||
elif args.command == "inspect":
|
||||
describe(args.torrent.read_bytes())
|
||||
else:
|
||||
ok, bad = verify(args.torrent.read_bytes(), args.file.read_bytes())
|
||||
print("OK" if ok else "FAILED", "bad pieces:", bad)
|
||||
return 0 if ok else 1
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
Reference in New Issue
Block a user