Skip to content

Commit 8da169e

Browse files
authored
Merge pull request #21 from desultory/dev
add hexdump with xxd like output
2 parents 793803e + f7903da commit 8da169e

File tree

2 files changed

+64
-0
lines changed

2 files changed

+64
-0
lines changed

src/zenlib/util/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from .colorize import colorize
22
from .dict_check import contains, unset
33
from .handle_plural import handle_plural
4+
from .hexdump import hexdump
45
from .main_funcs import get_args_n_logger, get_kwargs, get_kwargs_from_args, process_args
56
from .merge_class import merge_class
67
from .pretty_print import pretty_print
@@ -10,6 +11,7 @@
1011
__all__ = [
1112
"handle_plural",
1213
"colorize",
14+
"hexdump",
1315
"NoDupFlatList",
1416
"pretty_print",
1517
"replace_file_line",

src/zenlib/util/hexdump.py

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
from .colorize import colorize as c_
2+
3+
HEX_COLORS = {
4+
0: {"dim": True}, # Make null bytes dim
5+
32: {"dim": True}, # Make space dim
6+
}
7+
8+
# Make punctuation and special characters red
9+
for i in range(33, 48): # Special characters
10+
HEX_COLORS[i] = {"color": "red", "bold": True}
11+
for i in range(58, 65): # Special characters
12+
HEX_COLORS[i] = {"color": "red", "bold": True}
13+
for i in range(91, 97): # Special characters
14+
HEX_COLORS[i] = {"color": "red", "bold": True}
15+
for i in range(123, 127): # Special characters
16+
HEX_COLORS[i] = {"color": "red", "bold": True}
17+
18+
# Make ASCII numbers green and bold
19+
for i in range(48, 57): # decimal numbers
20+
HEX_COLORS[i] = {"color": "green", "bold": True}
21+
22+
# Make ASCII letters blue and bold
23+
for i in range(65, 91): # Uppercase A-Z
24+
HEX_COLORS[i] = {"color": "blue", "bold": True}
25+
for i in range(97, 123): # Lowercase a-z
26+
HEX_COLORS[i] = {"color": "blue", "bold": True}
27+
28+
# Make extended ASCII characters yellow and bold
29+
for i in range(128, 256): # Extended ASCII
30+
HEX_COLORS[i] = {"color": "yellow", "bold": True}
31+
32+
# Make control characters magenta
33+
for i in range(1, 32): # Control characters
34+
HEX_COLORS[i] = {"color": "magenta"}
35+
36+
37+
def get_hex_color(byte: int) -> str:
38+
"""Returns the colorized representation of a byte."""
39+
if byte in HEX_COLORS:
40+
color_data = HEX_COLORS[byte]
41+
return c_(f"{byte:02x}", **color_data)
42+
return c_(f"{byte:02x}", bold=True)
43+
44+
45+
def hexdump(data: bytes, length: int = 16) -> str:
46+
"""
47+
Returns a formatted hex dump of the given binary data.
48+
49+
Args:
50+
data (bytes): The binary data to be dumped.
51+
length (int): The number of bytes per line in the dump.
52+
53+
Returns:
54+
str: A formatted hex dump of the binary data.
55+
"""
56+
result = []
57+
for i in range(0, len(data), length):
58+
chunk = data[i : i + length]
59+
hex_part = " ".join(f"{get_hex_color(byte)}" for byte in chunk)
60+
ascii_part = "".join((c_(chr(byte), "green") if 32 <= byte < 127 else ".") for byte in chunk)
61+
result.append(f"{i:08x}: {hex_part:<{length * 3}} {ascii_part}")
62+
return "\n".join(result)

0 commit comments

Comments
 (0)