Created
December 13, 2022 13:39
-
-
Save ipid/1fd307753905271555704fe0c001f745 to your computer and use it in GitHub Desktop.
一个简单的工具,用来将文本转换为原始十六进制字符串。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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