Skip to content

Instantly share code, notes, and snippets.

@ipid
Created December 13, 2022 13:39
Show Gist options
  • Save ipid/1fd307753905271555704fe0c001f745 to your computer and use it in GitHub Desktop.
Save ipid/1fd307753905271555704fe0c001f745 to your computer and use it in GitHub Desktop.
一个简单的工具,用来将文本转换为原始十六进制字符串。
import sys
from pathlib import Path
from argparse import ArgumentParser
from dataclasses import dataclass
@dataclass
class Arguments:
upper: bool
separator: str
quotes: list[str]
mode: str
path: Path
def check_and_get_arguments() -> Arguments:
parser = ArgumentParser(
description='将文件转换为 16 进制字符串。\n(以下帮助内容中,假设文件内容总长 3 字节,内容为 3D 50 6C)\n')
group = parser.add_mutually_exclusive_group()
group.add_argument('-l', '--lower', action='store_true',
help='输出小写字母(默认为大写字母)。影响其它所有参数。')
parser.add_argument('-q', '--single-quote', action='append_const', dest='quotes', const="'",
help='输出的字符串两端会带上单引号。影响其它所有参数。')
parser.add_argument('-d', '--double-quote', action='append_const', dest='quotes', const='"',
help='输出的字符串两端会带上双引号。影响其它所有参数。')
parser.add_argument('-c', '--comma', action='append_const', const=',', dest='separators',
help='使用逗号做分隔符。影响其它所有参数。')
parser.add_argument('-s', '--space', action='append_const', const=' ', dest='separators',
help='使用空格做分隔符。影响其它所有参数。')
group = parser.add_mutually_exclusive_group()
group.add_argument('-r', '--raw', action='store_const', dest='mode', const='hex',
help='输出无分隔的 16 进制字符串,例如:3D506C')
group.add_argument('-0', '--0x', action='store_const', dest='mode', const='0x',
help='输出用 0x 分隔的 16 进制字符串,例如:0x3D0x500x6C。使用 -s(--space)即可在中间加入空格。')
group.add_argument('-x', action='store_const', dest='mode', const='x',
help=r'输出用 \x 分隔的 16 进制字符串,例如:\x3D\x50\x6C')
group.add_argument('-u', action='store_const', dest='mode', const='u',
help=r'输出用 \u00 分隔的 16 进制字符串,例如:\u003D\u0050\u006C。'
r'注意:该选项不会解析 Unicode 编码,而是会将每个字节以 \u00 为开头输出。')
parser.add_argument('path', type=Path)
args = parser.parse_args()
return Arguments(
upper=True if not args.lower else False,
separator=''.join(args.separators) if args.separators else '',
quotes=[] if not args.quotes else args.quotes,
mode='hex' if not args.mode else args.mode,
path=args.path,
)
def main():
args = check_and_get_arguments()
result = []
file_bytes = args.path.read_bytes()
for b in file_bytes:
hex_byte = hex(b).replace('0x', '').zfill(2)
if args.upper:
hex_byte = hex_byte.upper()
if args.mode == 'hex':
result.append(hex_byte)
elif args.mode == '0x':
result.append('0x' + hex_byte)
elif args.mode == 'x':
result.append(r'\x' + hex_byte)
elif args.mode == 'u':
result.append(r'\u00' + hex_byte)
result_str = args.separator.join(result)
for quote in args.quotes:
result_str = f'{quote}{result_str}{quote}'
print(result_str, end='')
print(f'\n\n文件长度: {len(file_bytes)} 字节', file=sys.stderr)
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment