Skip to content

Commit 507535f

Browse files
committed
sum: Add sum.py
1 parent 6c3142a commit 507535f

File tree

1 file changed

+63
-0
lines changed

1 file changed

+63
-0
lines changed

src/sum.py

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
#!/usr/bin/python3
2+
3+
import sys
4+
from optparse import OptionParser
5+
6+
7+
# BSD 16-bit checksum
8+
def sum_bsd(data: bytes) -> str:
9+
checksum = 0
10+
for b in data:
11+
checksum = (checksum >> 1) + ((checksum & 1) << 15)
12+
checksum += b
13+
checksum &= 0xFFFF
14+
15+
return f"{checksum:05}{-(len(data) // -1024):>6}"
16+
17+
18+
# SYSV checksum
19+
def sum_sysv(data: bytes) -> int:
20+
s = sum(data)
21+
r = s % 2**16 + (s % 2**32) // 2**16
22+
checksum = (r % 2**16) + r // 2**16
23+
24+
return f"{checksum:03} {-(len(data) // -512)}"
25+
26+
27+
SUM_ALGORITHMS = {"bsd": sum_bsd, "sysv": sum_sysv}
28+
29+
30+
def _sum(opts, filenames: list[str]):
31+
for name in filenames:
32+
if name == "-":
33+
print(SUM_ALGORITHMS[opts.algorithm](sys.stdin.buffer.read()))
34+
else:
35+
with open(name, "rb") as io:
36+
print(f"{SUM_ALGORITHMS[opts.algorithm](io.read())} {name}")
37+
38+
39+
if __name__ == "__main__":
40+
parser = OptionParser(
41+
usage="Usage: %prog [OPTION] [FILE]...", add_help_option=False
42+
)
43+
parser.add_option("--help", action="help", help="show usage information and exit")
44+
45+
parser.add_option(
46+
"-r",
47+
dest="algorithm",
48+
action="store_const",
49+
const="bsd",
50+
default="bsd",
51+
help="use the BSD (16-bit) checksum algorithm (1KiB blocks)",
52+
)
53+
parser.add_option(
54+
"-s",
55+
dest="algorithm",
56+
action="store_const",
57+
const="sysv",
58+
help="use the System V sum algorithm (512B blocks)",
59+
)
60+
61+
opts, args = parser.parse_args()
62+
63+
_sum(opts, args or ["-"])

0 commit comments

Comments
 (0)