diff --git a/TODO.norg b/TODO.norg index 411a4c1..33a119c 100644 --- a/TODO.norg +++ b/TODO.norg @@ -3,7 +3,12 @@ This is a list of tasks that would be cool to add. * Tasks ** Basic *** Files - - ( ) Hex dumper + - (-) Hex dumper + - (x) Dump basic files with format + - (x) Dump basic files with chars + - (x) Be able to dump larger files or put out an error + - ( ) Stop reading when read gets blocked /somehow/ + - ( ) Install script to system *** Networking - ( ) Mini curl *** Packaging diff --git a/Tasks.md b/Tasks.md index d56e6cc..1f12dbd 100644 --- a/Tasks.md +++ b/Tasks.md @@ -406,37 +406,84 @@ don't like windows either, so no support for installing stuff on windows. ### A. Hexdumper Difficulty: 3/5 - 1. Dump the data of [data/metasyntactic.md](./data/metasyntactic.md) -- In Hexadecimal. 2. Make the dumped Bytes look pretty, something like the example below: +3. Make use of command line arguments to add a help option (triggered with `-h` or + `--help`) and a `-C` or `--chars` option that adds another section that + prints the bytes interpreted as text. Those bytes that have no text + representation should be displayed as `.`. You may use the `argparse` library + to work with the arguments.
Hexdump Example Display -`data/metasyntactic.md` looks like this when hexdumped: +`data/metasyntactic.md` should look like this when hexdumped: ```text Line Data ================================================= -0000000 ┃ 6f4e 6574 203a 6854 7369 6920 2073 6874 -0000010 ┃ 2065 6957 696b 6570 6964 2061 6170 6567 -0000020 ┃ 6620 726f 6d20 7465 7361 6e79 6174 7463 -0000030 ┃ 6369 7620 7261 6169 6c62 7365 6920 206e -0000040 ┃ 6e45 6c67 7369 2c68 3220 3230 2d33 3930 -0000050 ┃ 302d 2e35 4620 6e69 2064 6874 0a65 7075 -0000060 ┃ 7420 206f 6164 6574 6f20 6972 6967 616e -0000070 ┃ 206c 685b 7265 5d65 6828 7474 7370 2f3a -0000080 ┃ 652f 2e6e 6977 696b 6570 6964 2e61 726f -0000090 ┃ 2f67 6977 696b 4d2f 7465 7361 6e79 6174 -00000a0 ┃ 7463 6369 765f 7261 6169 6c62 2965 0a2e -00000b0 ┃ 230a 4d20 7465 7361 6e79 6174 7463 6369 -00000c0 ┃ 7620 7261 6169 6c62 0a65 230a 2023 6f54 -00000d0 ┃ 6c6f 0a73 460a 6f72 206d 6957 696b 6570 -00000e0 ┃ 6964 2c61 7420 6568 6620 6572 2065 6e65 -00000f0 ┃ 7963 6c63 706f 6465 6169 540a 6968 2073 -0000100 ┃ 7261 6974 6c63 2065 7369 6120 6f62 7475 -0000110 ┃ 6d20 7465 7361 6e79 6174 7463 6369 7620 +0000000 | 6f4e 6574 203a 6854 7369 6920 2073 6874 +0000010 | 2065 6957 696b 6570 6964 2061 6170 6567 +0000020 | 6620 726f 6d20 7465 7361 6e79 6174 7463 +0000030 | 6369 7620 7261 6169 6c62 7365 6920 206e +0000040 | 6e45 6c67 7369 2c68 3220 3230 2d33 3930 +0000050 | 302d 2e35 4620 6e69 2064 6874 0a65 7075 +0000060 | 7420 206f 6164 6574 6f20 6972 6967 616e +0000070 | 206c 685b 7265 5d65 6828 7474 7370 2f3a +0000080 | 652f 2e6e 6977 696b 6570 6964 2e61 726f +0000090 | 2f67 6977 696b 4d2f 7465 7361 6e79 6174 +00000a0 | 7463 6369 765f 7261 6169 6c62 2965 0a2e +00000b0 | 230a 4d20 7465 7361 6e79 6174 7463 6369 +00000c0 | 7620 7261 6169 6c62 0a65 230a 2023 6f54 +00000d0 | 6c6f 0a73 460a 6f72 206d 6957 696b 6570 +00000e0 | 6964 2c61 7420 6568 6620 6572 2065 6e65 +00000f0 | 7963 6c63 706f 6465 6169 540a 6968 2073 +0000100 | 7261 6974 6c63 2065 7369 6120 6f62 7475 +0000110 | 6d20 7465 7361 6e79 6174 7463 6369 7620 +... +``` + +And like this when hexdumped with `-C`: + +```text +Line Data Text +====================================================================== +0000000 | 6f4e 6574 203a 6854 7369 6920 2073 6874 |Note: This is th| +0000010 | 2065 6957 696b 6570 6964 2061 6170 6567 |e Wikipedia page| +0000020 | 6620 726f 6d20 7465 7361 6e79 6174 7463 | for metasyntact| +0000030 | 6369 7620 7261 6169 6c62 7365 6920 206e |ic variables in | +0000040 | 6e45 6c67 7369 2c68 3220 3230 2d33 3930 |English, 2023-09| +0000050 | 302d 2e35 4620 6e69 2064 6874 0a65 7075 |-05. Find the.up| +0000060 | 7420 206f 6164 6574 6f20 6972 6967 616e | to date origina| +0000070 | 206c 685b 7265 5d65 6828 7474 7370 2f3a |l [here](https:/| +0000080 | 652f 2e6e 6977 696b 6570 6964 2e61 726f |/en.wikipedia.or| +0000090 | 2f67 6977 696b 4d2f 7465 7361 6e79 6174 |g/wiki/Metasynta| +00000a0 | 7463 6369 765f 7261 6169 6c62 2965 0a2e |ctic_variable)..| +00000b0 | 230a 4d20 7465 7361 6e79 6174 7463 6369 |.# Metasyntactic| +00000c0 | 7620 7261 6169 6c62 0a65 230a 2023 6f54 | variable..## To| +00000d0 | 6c6f 0a73 460a 6f72 206d 6957 696b 6570 |ols..From Wikipe| +00000e0 | 6964 2c61 7420 6568 6620 6572 2065 6e65 |dia, the free en| +00000f0 | 7963 6c63 706f 6465 6169 540a 6968 2073 |cyclopedia.This | ... ```
+ +
+Hints + + + +
+ +
+Solution + +[Code Example](./src/hexdumper.py) + +
+ +### B. Packaging your hexdumper + +1. Install `pip`, on debian based systems you can do that with `apt-get install + python3-pip`. diff --git a/src/caesar.py b/src/caesar.py old mode 100644 new mode 100755 diff --git a/src/hexdumper.py b/src/hexdumper.py new file mode 100755 index 0000000..c4604cb --- /dev/null +++ b/src/hexdumper.py @@ -0,0 +1,104 @@ +#!/usr/bin/env python3 +import argparse +import os +import sys + +# 2**30 bytes aka 1 Mebibyte +MAX_SIZE: int = 0x100000 + + + +def humanbytes(B): + """Return the given bytes as a human friendly KB, MB, GB, or TB string.""" + B = float(B) + KB = float(1024) + MB = float(KB ** 2) # 1,048,576 + GB = float(KB ** 3) # 1,073,741,824 + TB = float(KB ** 4) # 1,099,511,627,776 + + if B < KB: + return '{0} {1}'.format(B,'Bytes' if 0 == B > 1 else 'Byte') + elif KB <= B < MB: + return '{0:.2f} KB'.format(B / KB) + elif MB <= B < GB: + return '{0:.2f} MB'.format(B / MB) + elif GB <= B < TB: + return '{0:.2f} GB'.format(B / GB) + elif TB <= B: + return '{0:.2f} TB'.format(B / TB) + +def main(): + """Dump a file""" + # arg parsing + parser = argparse.ArgumentParser( + prog="hexer", + description="Dumps data as hex" + ) + parser.add_argument("file") + parser.add_argument("-c", "--chars", action="store_true") + args = parser.parse_args() + + # open file + try: + file = open(args.file, "rb") + except Exception as e: + print(f"Could not open file '{args.file}': {e}") + sys.exit(1) + + # check if the file has a reasonable size to dump + if 0 != os.path.getsize(args.file) > MAX_SIZE: + print(f"""The file you are trying to dump is larger than 1M.\n\ + Actual size: {humanbytes(os.path.getsize(args.file))}\nrefusing to dump""") + sys.exit(2) + # print header + if args.chars: + print("Line Data Text") + print('=' * 68) + else: + print(f"Line Data") + print('=' * 48) + + # every line should contain 16 bytes, so we need a loop that get's 16 bytes + # and then works with them + next: bytes = bytes(16) + index: int = 0 + while len(next) == 16: + next = file.read(16) + if len(next) == 0: + # no data left to read + break + + line: str = f"{index:07x} | " + + # actual hexdumping + for i in range(16): + if i % 2 == 0: + if len(next) > i+1: + line += f"{next[i]:02x}{next[i+1]:02x} " + elif len(next) > i: + line += f"{next[i]:02x} " + else: + line += " " + else: continue + + # if chars is enabled, print chars + if args.chars: + line += "| " + for b in next: + # special case for newline + if b == 0x0a: + line+= '␤' # official unicode symbol representing newlines + # only print regular characters + elif b > 0x20 and b < 0x7e: + line += chr(b) + elif b == 0x20: + line += '\u2420' + else: + line += '.' + + print(line) + index += 16 + + +if __name__ == "__main__": + main() diff --git a/src/tasks/hexdumper-a.py b/src/tasks/hexdumper-a.py deleted file mode 100755 index 7303f72..0000000 --- a/src/tasks/hexdumper-a.py +++ /dev/null @@ -1,8 +0,0 @@ -#!/usr/bin/env python3 -import sys - -def main(): - # parse args - -if __name__ == "__main__": - main()