Python 中如何格式化十六进制输出

PythonBeginner
立即练习

介绍

Python 是一种多功能的编程语言,允许你处理各种数值表示,包括十六进制。十六进制数在计算机科学中被广泛使用,用于表示内存地址、颜色代码以及以更紧凑形式表示的二进制数据等任务。在本教程中,你将学习如何在 Python 中格式化十六进制输出,理解其基本概念,并探索它的一些实际应用。

理解十六进制基础

十六进制(通常缩写为“hex”)是一种以 16 为基数的数字系统。与我们日常使用的十进制系统使用 10 个数字(0-9)不同,十六进制使用 16 个不同的符号:数字 0-9 和字母 A-F。

以下是每个十六进制数字在十进制中的表示:

  • 0-9 与十进制相同
  • A = 10
  • B = 11
  • C = 12
  • D = 13
  • E = 14
  • F = 15

二进制到十六进制的转换

十六进制的主要优点之一是它与二进制的便捷关系。每个十六进制数字正好代表 4 个二进制数字(位):

Binary: 0000 = Hex: 0
Binary: 0001 = Hex: 1
...
Binary: 1010 = Hex: A
...
Binary: 1111 = Hex: F

让我们创建一个简单的 Python 脚本来更好地理解十六进制:

  1. 在你的 LabEx 环境中打开 WebIDE(VSCode)界面。
  2. /home/labex/project 目录下创建一个名为 hex_basics.py 的新文件。
  3. 将以下代码添加到文件中:
## Understanding decimal, binary, and hexadecimal conversion
decimal_value = 42

## Convert decimal to binary
binary_value = bin(decimal_value)

## Convert decimal to hexadecimal
hex_value = hex(decimal_value)

## Print all representations
print(f"Decimal: {decimal_value}")
print(f"Binary: {binary_value}")
print(f"Hexadecimal: {hex_value}")

## Let's see a larger number
large_decimal = 255
print(f"\nDecimal: {large_decimal}")
print(f"Binary: {bin(large_decimal)}")
print(f"Hexadecimal: {hex(large_decimal)}")
  1. 保存文件。
  2. 要运行脚本,请在 WebIDE 中打开一个终端并执行:
python3 hex_basics.py

你应该看到类似这样的输出:

Decimal: 42
Binary: 0b101010
Hexadecimal: 0x2a

Decimal: 255
Binary: 0b11111111
Hexadecimal: 0xff

请注意,Python 会自动为这些数字添加前缀:

  • 二进制值以 0b 为前缀
  • 十六进制值以 0x 为前缀

这些前缀有助于区分代码中不同的数字系统。

Python 中的基本十六进制格式化

现在你已经理解了十六进制的基础知识,让我们学习如何在 Python 中格式化十六进制值。Python 提供了几种在十进制和十六进制之间转换的方法,并根据你的需要格式化输出。

在十进制和十六进制之间转换

让我们创建一个新文件来探索十六进制转换和格式化:

  1. 在 WebIDE 中,在 /home/labex/project 目录下创建一个名为 hex_formatting.py 的新文件。
  2. 将以下代码添加到文件中:
## Basic hexadecimal conversion examples

## Decimal to hex conversion
decimal_number = 171
hex_from_decimal = hex(decimal_number)
print(f"Decimal {decimal_number} converted to hex: {hex_from_decimal}")

## Hex to decimal conversion
hex_number = "0xAB"
decimal_from_hex = int(hex_number, 16)  ## The 16 specifies base-16 (hexadecimal)
print(f"Hex {hex_number} converted to decimal: {decimal_from_hex}")

## You can also use a hex literal directly in your code
hex_literal = 0xAB  ## This is already an integer in Python
print(f"Hex literal 0xAB as decimal: {hex_literal}")

## Working with binary and hexadecimal
binary_number = 0b10101011  ## Binary literal for 171
print(f"Binary {bin(binary_number)} as hex: {hex(binary_number)}")
  1. 保存文件。
  2. 使用以下命令运行脚本:
python3 hex_formatting.py

你应该看到类似这样的输出:

Decimal 171 converted to hex: 0xab
Hex 0xAB converted to decimal: 171
Hex literal 0xAB as decimal: 171
Binary 0b10101011 as hex: 0xab

理解输出格式

如你所见,当使用 hex() 函数将十进制转换为十六进制时,Python 返回一个带有 0x 前缀的字符串。这是许多编程语言中十六进制数的标准表示形式。

小写字母(a-f)是 Python 十六进制输出的默认设置,但你可能需要大写字母或不同的格式,具体取决于你的应用程序。

让我们修改我们的脚本来探索一些基本的格式化选项:

  1. 将以下代码添加到 hex_formatting.py 文件中:
## Controlling the case (uppercase/lowercase)
decimal_value = 171

## Default (lowercase)
hex_lowercase = hex(decimal_value)
print(f"\nDefault hex (lowercase): {hex_lowercase}")

## Using string methods to convert to uppercase
hex_uppercase = hex(decimal_value).upper()
print(f"Hex in uppercase: {hex_uppercase}")

## Removing the 0x prefix
hex_no_prefix = hex(decimal_value)[2:]  ## Slicing the string to remove first 2 chars
print(f"Hex without 0x prefix: {hex_no_prefix}")

## Adding padding for consistent width (2 digits with leading zeros)
hex_padded = f"{decimal_value:02x}"  ## Format specifier for 2-digit hex
print(f"Hex padded to 2 digits: {hex_padded}")

## 4-digit hex with leading zeros
hex_padded_4 = f"{decimal_value:04x}"
print(f"Hex padded to 4 digits: {hex_padded_4}")
  1. 保存文件。
  2. 再次运行脚本:
python3 hex_formatting.py

新的输出部分应该如下所示:

Default hex (lowercase): 0xab
Hex in uppercase: 0XAB
Hex without 0x prefix: ab
Hex padded to 2 digits: ab
Hex padded to 4 digits: 00ab

这演示了在 Python 中操作十六进制输出格式的一些简单方法。在下一步中,我们将探索更高级的格式化选项。

高级十六进制格式化技术

现在你已经理解了十六进制转换和简单格式化的基础知识,让我们探索更高级的格式化技术。Python 提供了强大的字符串格式化功能,可以应用于十六进制值。

使用字符串格式化方法

让我们创建一个新文件来探索不同的格式化选项:

  1. 在 WebIDE 中,在 /home/labex/project 目录下创建一个名为 advanced_hex_formatting.py 的新文件。
  2. 将以下代码添加到文件中:
## Advanced hexadecimal formatting techniques in Python

decimal_value = 171  ## This will be our example number throughout

print("Different ways to format hexadecimal output in Python:")
print("-" * 50)

## 1. Using format() function
print("\n1. Using the format() function:")
## Basic format (lowercase, no prefix)
print(f"Basic format: {format(decimal_value, 'x')}")
## Uppercase format
print(f"Uppercase: {format(decimal_value, 'X')}")
## With 0x prefix
print(f"With 0x prefix: {format(decimal_value, '#x')}")
## With 0X prefix and uppercase
print(f"With 0X prefix and uppercase: {format(decimal_value, '#X')}")
## Padding to 4 digits
print(f"Padded to 4 digits: {format(decimal_value, '04x')}")
## Padding with spaces
print(f"Padded with spaces: {format(decimal_value, '6x')}")

## 2. Using f-strings (Python 3.6+)
print("\n2. Using f-strings:")
## Basic hex
print(f"Basic format: {decimal_value:x}")
## Uppercase
print(f"Uppercase: {decimal_value:X}")
## With 0x prefix
print(f"With 0x prefix: {decimal_value:#x}")
## With 0X prefix and uppercase
print(f"With 0X prefix and uppercase: {decimal_value:#X}")
## Padding to 4 digits with zeros
print(f"Padded to 4 digits: {decimal_value:04x}")
## Centered in a 10-character field
print(f"Centered: {decimal_value:^10x}")

## 3. Using the str.format() method
print("\n3. Using str.format() method:")
## Basic format
print("Basic format: {:x}".format(decimal_value))
## Uppercase with 0X prefix
print("Uppercase with prefix: {:#X}".format(decimal_value))
## Padding with different align options
print("Right-aligned in 6 spaces: {:>6x}".format(decimal_value))
print("Left-aligned in 6 spaces: {:<6x}".format(decimal_value))
  1. 保存文件。
  2. 运行脚本:
python3 advanced_hex_formatting.py

输出将显示各种十六进制格式化选项:

Different ways to format hexadecimal output in Python:
--------------------------------------------------

1. Using the format() function:
Basic format: ab
Uppercase: AB
With 0x prefix: 0xab
With 0X prefix and uppercase: 0XAB
Padded to 4 digits: 00ab
Padded with spaces:     ab

2. Using f-strings:
Basic format: ab
Uppercase: AB
With 0x prefix: 0xab
With 0X prefix and uppercase: 0XAB
Padded to 4 digits: 00ab
Centered:     ab

3. Using str.format() method:
Basic format: ab
Uppercase with prefix: 0XAB
Right-aligned in 6 spaces:     ab
Left-aligned in 6 spaces: ab

创建一个字节数组的十六进制转储

十六进制格式化的一种常见应用是创建二进制数据的十六进制转储。让我们创建一个简单的函数来显示字节数组的十六进制转储:

  1. 将以下代码添加到 advanced_hex_formatting.py 文件中:
## 4. Creating a hex dump of binary data
print("\n4. Creating a hex dump of binary data:")

def hex_dump(data, bytes_per_line=16):
    """Display a hex dump of binary data with both hex and ASCII representation."""
    result = []

    for i in range(0, len(data), bytes_per_line):
        chunk = data[i:i+bytes_per_line]
        ## Create the hex representation
        hex_repr = ' '.join(f'{b:02x}' for b in chunk)

        ## Create the ASCII representation (printable chars only)
        ascii_repr = ''.join(chr(b) if 32 <= b <= 126 else '.' for b in chunk)

        ## Format the line with address, hex values, and ASCII representation
        line = f"{i:04x}: {hex_repr:<{bytes_per_line*3}} {ascii_repr}"
        result.append(line)

    return '\n'.join(result)

## Example: Creating some sample binary data
sample_data = bytes([
    0x48, 0x65, 0x6C, 0x6C, 0x6f, 0x20, 0x57, 0x6f, 0x72, 0x6c, 0x64, 0x21,  ## "Hello World!"
    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B,  ## Control characters
    0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x7F                                ## More control chars
])

## Print the hex dump
print(hex_dump(sample_data))
  1. 保存文件。
  2. 再次运行脚本:
python3 advanced_hex_formatting.py

输出的新部分将显示字节数组的十六进制转储:

4. Creating a hex dump of binary data:
0000: 48 65 6c 6c 6f 20 57 6f 72 6c 64 21 00 01 02 03 Hello World!....
0010: 04 05 06 07 08 09 0a 0b 1a 1b 1c 1d 1e 1f 7f    ...............

这种十六进制转储格式通常用于检查二进制数据、网络数据包或文件内容。每一行显示:

  • 十六进制的地址/偏移量
  • 每个字节的十六进制值
  • ASCII 表示形式(可打印字符直接显示,不可打印字符显示为点)

这些高级格式化技术为你提供了在 Python 程序中使用十六进制数据的强大工具。

Python 中十六进制的实际应用

现在你已经学习了如何在 Python 中格式化十六进制值,让我们探索一些十六进制格式化特别有用的实际应用。

1. 使用 RGB 颜色值

十六进制通常用于表示 Web 开发和图形编程中的颜色。RGB 颜色值可以表示为十六进制三元组,格式为 #RRGGBB

让我们创建一个脚本来演示如何使用十六进制处理颜色:

  1. 在 WebIDE 中,在 /home/labex/project 目录下创建一个名为 hex_color_converter.py 的新文件。
  2. 将以下代码添加到文件中:
## Working with RGB color values using hexadecimal

def rgb_to_hex(r, g, b):
    """Convert RGB values to a hexadecimal color string."""
    ## Ensure values are within valid range (0-255)
    r = max(0, min(255, r))
    g = max(0, min(255, g))
    b = max(0, min(255, b))

    ## Create hex string with ## prefix
    return f"#{r:02x}{g:02x}{b:02x}"

def hex_to_rgb(hex_color):
    """Convert a hexadecimal color string to RGB values."""
    ## Remove ## if present
    hex_color = hex_color.lstrip('#')

    ## Convert hex to decimal
    if len(hex_color) == 3:  ## Handle shorthand hex (#RGB)
        r = int(hex_color[0] + hex_color[0], 16)
        g = int(hex_color[1] + hex_color[1], 16)
        b = int(hex_color[2] + hex_color[2], 16)
    else:  ## Handle full hex (#RRGGBB)
        r = int(hex_color[0:2], 16)
        g = int(hex_color[2:4], 16)
        b = int(hex_color[4:6], 16)

    return (r, g, b)

## Example usage
print("RGB to Hex Color Conversion Examples:")
print("-" * 40)

## Common colors
colors = [
    (255, 0, 0),      ## Red
    (0, 255, 0),      ## Green
    (0, 0, 255),      ## Blue
    (255, 255, 0),    ## Yellow
    (255, 0, 255),    ## Magenta
    (0, 255, 255),    ## Cyan
    (255, 255, 255),  ## White
    (0, 0, 0)         ## Black
]

## Convert and display each color
for rgb in colors:
    hex_color = rgb_to_hex(*rgb)
    print(f"RGB: {rgb} → Hex: {hex_color}")

print("\nHex to RGB Color Conversion Examples:")
print("-" * 40)

## List of hex colors to convert
hex_colors = ["#ff0000", "#00ff00", "#0000ff", "#ff0", "#f0f", "#0ff"]

for hex_color in hex_colors:
    rgb = hex_to_rgb(hex_color)
    print(f"Hex: {hex_color} → RGB: {rgb}")

## Color blending example
print("\nColor Blending Example:")
print("-" * 40)

def blend_colors(color1, color2, ratio=0.5):
    """Blend two colors according to the given ratio."""
    r1, g1, b1 = hex_to_rgb(color1)
    r2, g2, b2 = hex_to_rgb(color2)

    r = int(r1 * (1 - ratio) + r2 * ratio)
    g = int(g1 * (1 - ratio) + g2 * ratio)
    b = int(b1 * (1 - ratio) + b2 * ratio)

    return rgb_to_hex(r, g, b)

## Blend red and blue with different ratios
red = "#ff0000"
blue = "#0000ff"

print(f"Color 1: {red} (Red)")
print(f"Color 2: {blue} (Blue)")

for i in range(0, 11, 2):
    ratio = i / 10
    blended = blend_colors(red, blue, ratio)
    print(f"Blend ratio {ratio:.1f}: {blended}")
  1. 保存文件。
  2. 运行脚本:
python3 hex_color_converter.py

输出将显示 RGB 和十六进制颜色格式之间的转换:

RGB to Hex Color Conversion Examples:
----------------------------------------
RGB: (255, 0, 0) → Hex: #ff0000
RGB: (0, 255, 0) → Hex: #00ff00
RGB: (0, 0, 255) → Hex: #0000ff
RGB: (255, 255, 0) → Hex: #ffff00
RGB: (255, 0, 255) → Hex: #ff00ff
RGB: (0, 255, 255) → Hex: #00ffff
RGB: (255, 255, 255) → Hex: #ffffff
RGB: (0, 0, 0) → Hex: #000000

Hex to RGB Color Conversion Examples:
----------------------------------------
Hex: #ff0000 → RGB: (255, 0, 0)
Hex: #00ff00 → RGB: (0, 255, 0)
Hex: #0000ff → RGB: (0, 0, 255)
Hex: #ff0 → RGB: (255, 255, 0)
Hex: #f0f → RGB: (255, 0, 255)
Hex: #0ff → RGB: (0, 255, 255)

Color Blending Example:
----------------------------------------
Color 1: #ff0000 (Red)
Color 2: #0000ff (Blue)
Blend ratio 0.0: #ff0000
Blend ratio 0.2: #cc0033
Blend ratio 0.4: #990066
Blend ratio 0.6: #660099
Blend ratio 0.8: #3300cc
Blend ratio 1.0: #0000ff

2. 使用二进制数据和文件操作

十六进制通常用于处理二进制数据,例如文件内容或网络数据包。让我们创建一个简单的十六进制文件查看器:

  1. 在 WebIDE 中,在 /home/labex/project 目录下创建一个名为 hex_file_viewer.py 的新文件。
  2. 将以下代码添加到文件中:
## Hexadecimal file viewer

def hex_dump(data, bytes_per_line=16, offset=0):
    """Create a hex dump of binary data."""
    result = []

    for i in range(0, len(data), bytes_per_line):
        chunk = data[i:i+bytes_per_line]
        ## Hex representation
        hex_part = ' '.join(f'{b:02x}' for b in chunk)
        ## ASCII representation
        ascii_part = ''.join(chr(b) if 32 <= b <= 126 else '.' for b in chunk)

        ## Add line to result
        line = f"{offset+i:08x}:  {hex_part:<{bytes_per_line*3}}  |{ascii_part}|"
        result.append(line)

    return '\n'.join(result)

def create_sample_file():
    """Create a sample binary file for demonstration."""
    file_path = "/home/labex/project/sample.bin"

    ## Create some sample data containing:
    ## - Some text
    ## - A range of values from 0-255
    sample_data = bytearray(b"This is a sample binary file.\n")
    sample_data.extend(range(0, 256))

    ## Write to file
    with open(file_path, 'wb') as f:
        f.write(sample_data)

    return file_path

def view_file_as_hex(file_path, max_bytes=256):
    """View a portion of the file as a hex dump."""
    try:
        with open(file_path, 'rb') as f:
            data = f.read(max_bytes)

        print(f"Hex dump of the first {len(data)} bytes of {file_path}:")
        print("-" * 70)
        print(hex_dump(data))

        if max_bytes < 256:
            print(f"\nOnly showing first {max_bytes} bytes. Adjust max_bytes parameter to see more.")

    except FileNotFoundError:
        print(f"Error: File '{file_path}' not found.")
    except Exception as e:
        print(f"Error reading file: {e}")

## Create a sample file and view it
sample_file = create_sample_file()
view_file_as_hex(sample_file, 128)

## Information about the "hex" command in Linux
print("\nFun fact: In Linux, you can use the 'hexdump' or 'xxd' commands")
print("to view binary files in hexadecimal format directly from the terminal.")
  1. 保存文件。
  2. 运行脚本:
python3 hex_file_viewer.py

输出将显示示例二进制文件的十六进制转储:

Hex dump of the first 128 bytes of /home/labex/project/sample.bin:
----------------------------------------------------------------------
00000000:  54 68 69 73 20 69 73 20 61 20 73 61 6d 70 6c 65  |This is a sample|
00000010:  20 62 69 6e 61 72 79 20 66 69 6c 65 2e 0a 00 01  | binary file...|
00000020:  02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11  |................|
00000030:  12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21  |.............. !|
00000040:  22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31  |"#$%&'()*+,-./01|
00000050:  32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f 40 41  |23456789:;<=>?@A|
00000060:  42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51  |BCDEFGHIJKLMNOPQ|
00000070:  52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f 60 61  |RSTUVWXYZ[\]^_`a|

Fun fact: In Linux, you can use the 'hexdump' or 'xxd' commands
to view binary files in hexadecimal format directly from the terminal.

此十六进制查看器显示每个字节的十六进制表示形式及其 ASCII 等效项,这是一种用于检查二进制数据的常见格式。

这些实际示例演示了十六进制格式化在实际 Python 应用程序中的用途。从颜色操作到二进制数据分析,十六进制提供了一种紧凑而有效的方式来表示和处理各种类型的数据。

总结

在本教程中,你已经学习了:

  • 十六进制数制的基础知识及其与二进制和十进制的关系
  • 如何在 Python 中进行十进制和十六进制值之间的转换
  • 各种格式化十六进制输出的技术,包括:
    • 使用 hex() 函数进行基本转换
    • 使用不同的前缀、填充和大小写选项进行格式化
    • 创建格式化的二进制数据十六进制转储
  • 十六进制在 Python 中的实际应用:
    • 在 Web 和图形开发中使用 RGB 颜色值
    • 使用十六进制转储分析二进制数据和文件内容

理解十六进制格式化是许多编程任务的一项基本技能,尤其是在处理底层操作、二进制数据或需要紧凑表示的领域时。你在本教程中学习的技术将帮助你更有效地处理 Python 程序中的各种数据格式。

为了进一步提升你在这方面的知识,你可能需要探索:

  • Python 中的位运算
  • 网络编程和数据包分析
  • 计算机图形学和图像处理
  • 内存管理和系统编程