basic hexdumper
This commit is contained in:
parent
778abfa7cc
commit
61dbf7a500
|
@ -3,7 +3,12 @@ This is a list of tasks that would be cool to add.
|
||||||
* Tasks
|
* Tasks
|
||||||
** Basic
|
** Basic
|
||||||
*** Files
|
*** 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
|
*** Networking
|
||||||
- ( ) Mini curl
|
- ( ) Mini curl
|
||||||
*** Packaging
|
*** Packaging
|
||||||
|
|
87
Tasks.md
87
Tasks.md
|
@ -406,37 +406,84 @@ don't like windows either, so no support for installing stuff on windows.
|
||||||
### A. Hexdumper
|
### A. Hexdumper
|
||||||
Difficulty: 3/5
|
Difficulty: 3/5
|
||||||
|
|
||||||
|
|
||||||
1. Dump the data of [data/metasyntactic.md](./data/metasyntactic.md) -- In
|
1. Dump the data of [data/metasyntactic.md](./data/metasyntactic.md) -- In
|
||||||
Hexadecimal.
|
Hexadecimal.
|
||||||
2. Make the dumped Bytes look pretty, something like the example below:
|
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.
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
<summary>Hexdump Example Display</summary>
|
<summary>Hexdump Example Display</summary>
|
||||||
|
|
||||||
`data/metasyntactic.md` looks like this when hexdumped:
|
`data/metasyntactic.md` should look like this when hexdumped:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
Line Data
|
Line Data
|
||||||
=================================================
|
=================================================
|
||||||
0000000 ┃ 6f4e 6574 203a 6854 7369 6920 2073 6874
|
0000000 | 6f4e 6574 203a 6854 7369 6920 2073 6874
|
||||||
0000010 ┃ 2065 6957 696b 6570 6964 2061 6170 6567
|
0000010 | 2065 6957 696b 6570 6964 2061 6170 6567
|
||||||
0000020 ┃ 6620 726f 6d20 7465 7361 6e79 6174 7463
|
0000020 | 6620 726f 6d20 7465 7361 6e79 6174 7463
|
||||||
0000030 ┃ 6369 7620 7261 6169 6c62 7365 6920 206e
|
0000030 | 6369 7620 7261 6169 6c62 7365 6920 206e
|
||||||
0000040 ┃ 6e45 6c67 7369 2c68 3220 3230 2d33 3930
|
0000040 | 6e45 6c67 7369 2c68 3220 3230 2d33 3930
|
||||||
0000050 ┃ 302d 2e35 4620 6e69 2064 6874 0a65 7075
|
0000050 | 302d 2e35 4620 6e69 2064 6874 0a65 7075
|
||||||
0000060 ┃ 7420 206f 6164 6574 6f20 6972 6967 616e
|
0000060 | 7420 206f 6164 6574 6f20 6972 6967 616e
|
||||||
0000070 ┃ 206c 685b 7265 5d65 6828 7474 7370 2f3a
|
0000070 | 206c 685b 7265 5d65 6828 7474 7370 2f3a
|
||||||
0000080 ┃ 652f 2e6e 6977 696b 6570 6964 2e61 726f
|
0000080 | 652f 2e6e 6977 696b 6570 6964 2e61 726f
|
||||||
0000090 ┃ 2f67 6977 696b 4d2f 7465 7361 6e79 6174
|
0000090 | 2f67 6977 696b 4d2f 7465 7361 6e79 6174
|
||||||
00000a0 ┃ 7463 6369 765f 7261 6169 6c62 2965 0a2e
|
00000a0 | 7463 6369 765f 7261 6169 6c62 2965 0a2e
|
||||||
00000b0 ┃ 230a 4d20 7465 7361 6e79 6174 7463 6369
|
00000b0 | 230a 4d20 7465 7361 6e79 6174 7463 6369
|
||||||
00000c0 ┃ 7620 7261 6169 6c62 0a65 230a 2023 6f54
|
00000c0 | 7620 7261 6169 6c62 0a65 230a 2023 6f54
|
||||||
00000d0 ┃ 6c6f 0a73 460a 6f72 206d 6957 696b 6570
|
00000d0 | 6c6f 0a73 460a 6f72 206d 6957 696b 6570
|
||||||
00000e0 ┃ 6964 2c61 7420 6568 6620 6572 2065 6e65
|
00000e0 | 6964 2c61 7420 6568 6620 6572 2065 6e65
|
||||||
00000f0 ┃ 7963 6c63 706f 6465 6169 540a 6968 2073
|
00000f0 | 7963 6c63 706f 6465 6169 540a 6968 2073
|
||||||
0000100 ┃ 7261 6974 6c63 2065 7369 6120 6f62 7475
|
0000100 | 7261 6974 6c63 2065 7369 6120 6f62 7475
|
||||||
0000110 ┃ 6d20 7465 7361 6e79 6174 7463 6369 7620
|
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 |
|
||||||
...
|
...
|
||||||
```
|
```
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary>Hints</summary>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary>Solution</summary>
|
||||||
|
|
||||||
|
[Code Example](./src/hexdumper.py)
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
### B. Packaging your hexdumper
|
||||||
|
|
||||||
|
1. Install `pip`, on debian based systems you can do that with `apt-get install
|
||||||
|
python3-pip`.
|
||||||
|
|
|
@ -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()
|
|
@ -1,8 +0,0 @@
|
||||||
#!/usr/bin/env python3
|
|
||||||
import sys
|
|
||||||
|
|
||||||
def main():
|
|
||||||
# parse args
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
main()
|
|
Loading…
Reference in New Issue