Implement command line and hex to string

This commit is contained in:
Tim Van Baak 2022-12-13 13:27:18 -08:00
parent f1fc39bc7a
commit 00505506c5
3 changed files with 99 additions and 2 deletions

1
.gitignore vendored
View File

@ -1 +1,2 @@
__pycache__/ __pycache__/
*.pyc

View File

@ -1,11 +1,58 @@
import argparse import argparse
import sys
import fhex.parse
def main(): def main():
parser = argparse.ArgumentParser() parser = argparse.ArgumentParser(
description="Convert hex strings to and from human-readable strings.")
parser.add_argument("-f", "--format", default="APNF")
parser.add_argument("-x", "--hex", nargs="?", const="-",
help="Hex code to translate to friendly string. If no value is" +
" specified, read hex from stdin.")
parser.add_argument("-s", "--string", nargs="?", const="-",
help="Friendly string to translate to hex. If no value is specified," +
" read string from stdin.")
parser.add_argument("--titlecase", action="store_true",
help="Titlecase friendly string output.")
parser.add_argument("--hyphenate", action="store_true",
help="Hyphenate friendly string output.")
parser.add_argument("-v", "--verbose", action="store_true")
args = parser.parse_args() args = parser.parse_args()
print("Hello, world!") if args.verbose:
print("friendly-hex", file=sys.stderr)
print(" --format =", args.format, file=sys.stderr)
print(" --hex =", args.hex, file=sys.stderr)
print(" --string =", args.string, file=sys.stderr)
print(" --titlecase =", args.titlecase, file=sys.stderr)
print(" --hyphenate =", args.hyphenate, file=sys.stderr)
print(" --verbose =", args.verbose, file=sys.stderr)
print(file=sys.stderr)
if args.hex is None and args.string is None:
parser.error("One of --hex or --string is required.")
if args.hex is not None and args.string is None:
# Convert hex to friendly string
if args.hex == "-":
args.hex = sys.stdin.readline().strip()
if args.verbose:
print(f'Read "{args.hex}" from stdin', file=sys.stderr)
words = fhex.parse.hex_to_friendly(args.hex, args.format)
if args.titlecase:
words = [word.title() for word in words]
joiner = "-" if args.hyphenate else " "
joined = joiner.join(words)
print(joined)
if args.hex is None and args.string is not None:
# Convert friendly string to hex
raise NotImplementedError()
if __name__ == "__main__": if __name__ == "__main__":

49
fhex/parse.py Normal file
View File

@ -0,0 +1,49 @@
import math
from fhex.words import ADJECTIVE, PARTICIPLE, NOUN, PHONETIC
DEFAULT_FORMAT_DEF = {
"A": ADJECTIVE,
"P": PARTICIPLE,
"N": NOUN,
"F": PHONETIC,
}
def hex_to_friendly(hex_str, format_str):
hex_i, fmt_i = 0, 0
words = []
fmt_def = DEFAULT_FORMAT_DEF
while hex_i < len(hex_str):
if fmt_i >= len(format_str):
raise Exception("Format string is too short")
fmt_code = format_str[fmt_i]
if fmt_code not in fmt_def:
raise Exception(f"Unrecognized format code: {fmt_code}")
fmt_list = fmt_def[fmt_code]
fmt_len = math.log(len(fmt_list), 16)
if fmt_len % 1 != 0:
raise Exception(
f"Word list for {fmt_code} must be a power of 16" +
" (length: {len(fmt_list)})")
fmt_len = int(fmt_len)
if hex_i + fmt_len > len(hex_str):
raise Exception(f"Not enough hex characters for format code {fmt_code}")
hex_part = hex_str[hex_i:hex_i + fmt_len]
fmt_list_i = int(hex_part, 16)
word = fmt_list[fmt_list_i]
words.append(word)
hex_i += fmt_len
fmt_i += 1
if fmt_i != len(format_str):
raise Exception("Format string is too long")
return words