将MiB/KiB转换为十六进制的脚本';0x';表示法和do添加(Python)

将MiB/KiB转换为十六进制的脚本';0x';表示法和do添加(Python),python,python-3.x,hex,Python,Python 3.x,Hex,试图理解有关MiB(mebibytes)和KiB(kibibytes)中内存位置和大小的十六进制0x表示法。具体而言,在分区布局表中,我可以看到以下列: size hex '0x' notation 1 MiB 0x0010 0000 12 MiB 0x00c0 0000 128 KiB 0x0002 0000 但我发现自己很难翻译/提取逻辑来计算和进行转换(例如从24mib、125kib、16mib转换为“0x”十六进

试图理解有关MiB(mebibytes)和KiB(kibibytes)中内存位置和大小的十六进制
0x
表示法。具体而言,在分区布局表中,我可以看到以下列:

size        hex '0x' notation           
1 MiB       0x0010 0000    
12 MiB      0x00c0 0000
128 KiB     0x0002 0000
但我发现自己很难翻译/提取逻辑来计算和进行转换(例如从24mib、125kib、16mib转换为“0x”十六进制符号等)

因此,我考虑编写一个
Python
脚本(正如您所做的那样)来完成从MiB/KiB到“Ox”的转换,并添加“0x”
。我发现了这个[但我没有从中做任何有意义的事情]

令我惊讶的是,我在网上找不到任何东西来帮助我完成从MiB/KiB到十六进制“0x”表示法的转换。在
Python
中,我找到了
hex
函数,试图在十六进制“0x”表示法中的十六进制值之间进行基本加法:

def hex_add(h1, h2):
    return hex(int(h1, 0) + int(h2, 0))
如何使用
Python
(内置或非内置函数)自动计算从MiB到十六进制“0x”表示法的转换?另外,
hex\u add
是否足以对“0x”表示法执行添加


Python
中演示转换和加法的一些代码示例将非常有用。

首先,让我们为KiB、MiB、GiB等创建一些常量。这里不必担心十六进制,我们只需要对您最有意义的任何形式的数字,无论是
1024
还是
0x400
还是
2**10
d没关系,因为它们都是相同的数字。所以:

KiB = 1024
MiB = 1024 * KiB
GiB = 1024 * MiB
TiB = 1024 * GiB
现在,12MB是多少?很简单:

12 * MiB
现在,12兆十六进制是多少

hex(12 * MiB)
这将为您提供
'0xc00000'


至于“在十六进制中添加”,您不应该这样做。只需将数字添加为数字,然后将结果格式化为十六进制。例如,如果您要添加32KiB+16KiB+1MiB:

hex(32*KiB + 16*KiB + 1*MiB)

您希望对输出进行更多的控制。如果这很重要,您需要使用(无论是通过
format
函数、
str.format
方法还是f-string文本)而不是
hex

您可以指定要填充的宽度和填充字符。您还可以使用
#
自动添加
0x
(在这种情况下,我们必须填充到8+2=10个字符,而不是8个),或者手动添加
0x
(在这种情况下,我们只需填充到8个字符,这更有意义):

您还希望将数字分成4个块。我们可以使用分组字符使其非常接近,但我们必须在宽度上添加额外的1:

f"0x{12*MiB:09_x}"
…此时,我们不妨再次使用

f"{12*MiB:#011_x}"
现在您已经有了
'0x00c0\u 0000'
。如果组之间确实需要空格而不是下划线,那么您需要稍微难看一点:

f"{12*MiB:#11_x}".replace('_', ' ')
(我相信有人提议允许任意分组字符,但被拒绝了,所以唯一的选项是“按我的语言环境说的做”。)


因此,如果要打印出表格:

print( "size        hex '0x' notation")
print(f"1 MiB       {12*MiB:#011_x}")
print(f"12 KiB      {12*KiB:#011_x}")
print(f"128 KiB     {128*KiB:#011_x}")
或者您可以编写一个函数。在编写过程中,让我们使用
Enum
而不是一堆单独的常量:

import enum
class Prefixes(enum.Enum):
    Ki = 1024
    Mi = 1024 * Ki
    Gi = 1024 * Mi
    Ti = 1024 * Gi
def printrow(n, prefix):
    label = f"{n} {prefix.name}B"
    print(f"{label:<12}{n * prefix.value:#011_x}")
print("size        hex '0x' notation")
printrow(1, Prefixes.Mi)
printrow(12, Prefixes.Ki)
printrow(128, Prefixes.Ki)
导入枚举
类前缀(enum.enum):
Ki=1024
Mi=1024*Ki
Gi=1024*Mi
Ti=1024*Gi
def打印行(n,前缀):
label=f“{n}{prefix.name}B”

打印(f){label:回答得很好!但是,你说
12 MiB=0x0c0_0000
,而在问题的表格上,它等于
0x00c0 0000
。这两者都是一样的吗?我知道我的问题可能是因为我对十六进制缺乏了解。@Karim Oops,我忘记了分组字符是宽度的一部分。编辑了答案以解决此问题。但同时,less,
0x0c0_0000
的值与
0x00c0_0000
的值相同。前导零没有任何意义,就像日常算术中的
0123
00123
是相同的数字一样。
import enum
class Prefixes(enum.Enum):
    Ki = 1024
    Mi = 1024 * Ki
    Gi = 1024 * Mi
    Ti = 1024 * Gi
def printrow(n, prefix):
    label = f"{n} {prefix.name}B"
    print(f"{label:<12}{n * prefix.value:#011_x}")
print("size        hex '0x' notation")
printrow(1, Prefixes.Mi)
printrow(12, Prefixes.Ki)
printrow(128, Prefixes.Ki)