在 PowerShell 中将十六进制字符串转换为 base 64
Converting a hex string to base 64 in PowerShell
我正在尝试在 PowerShell 中复制以下 Python 片段的功能:
allowed_mac_separators = [':', '-', '.']
for sep in allowed_mac_separators:
if sep in mac_address:
test = codecs.decode(mac_address.replace(sep, ''), 'hex')
b64_mac_address = codecs.encode(test, 'base64')
address = codecs.decode(b64_mac_address, 'utf-8').rstrip()
它接受一个MAC地址,删除分隔符,将其转换为十六进制,然后是base64。 (我没有编写 Python 函数,无法控制它或它如何工作。)
例如,MAC 地址 AA:BB:CC:DD:E2:00
将被转换为 AABBCCDDE200
,然后是 b'\xaa\xbb\xcc\xdd\xe2\x00'
,最后作为输出 b'qrvM3eIA'
。我尝试做类似的事情:
$bytes = 'AABBCCDDE200' | Format-Hex
[System.BitConverter]::ToString($bytes);
但这会产生 MethodException: Cannot find an overload for "ToString" and the argument count: "1".
,我不太确定它在寻找什么。我发现的所有使用该调用的示例都只有一个参数。这有效:
[System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes('AABBCCDDE200'))
但显然不会先将其转换为十六进制,因此会产生不正确的结果。感谢任何帮助。
# Remove everything except word characters from the string.
# In effect, this removes any punctuation ('-', ':', '.')
$sanitizedHexStr = 'AA:BB:CC:DD:E2:00' -replace '\W'
# Convert all hex-digit pairs in the string to an array of bytes.
$bytes = [byte[]] -split ($sanitizedHexStr -replace '..', '0x$& ')
# Get the Base64 encoding of the byte array.
[System.Convert]::ToBase64String($bytes)
有关用于创建 $bytes
数组的技术的说明,以及更简单的 PowerShell(核心)7.1+ / .NET 5+ 替代方案(简而言之:[System.Convert]::FromHexString('AABBCCDDE200')
),参见 .
至于你试过的:
Format-Hex
不是return字节数组(直接),它的主要目的是可视化 十六进制格式的输入数据对于人类观察者。
一般来说,Format-*
cmdlet 输出对象的唯一目的是向 PowerShell 的输出格式化系统提供 格式化指令 - 请参阅 this answer。简而言之:只使用 Format-*
cmdlet 来格式化数据 以供显示 ,永远不要用于后续 程序化处理 .
也就是说,在 Format-Hex
的特定情况下,输出对象 的类型 [Microsoft.PowerShell.Commands.ByteCollection]
, do contain useful data, and do contain the bytes of the transcoded characters of input strings .Bytes
property, as Cpt.Whale 指出。
但是,$bytes = ($sanitizedHexStr | Format-Hex).Bytes
将 不适用于您的情况,因为您将有效地获得反映 ASCII 代码点 [=91] 的字节值=] 等字符 A
(见下文) - 而你需要的是将这些字符解释为 十六进制数字 .
但即使在一般情况下我建议不要依赖Format-Hex
进行到字节数组的转换:
如前所述,Format-*
cmdlet 的目的是产生 for-display 输出,而不是 data,值得观察这个区别,尽管有这个例外——输出对象的类型可以被认为是一个实现细节。
Format-Hex
根据首先应用 固定字符转码 将字符串转换为字节(例如,您无法获得.NET 字符串 原样,基于 UTF-16 代码单元),并且 之间的固定转码 Windows PowerShell 和 PowerShell(核心):
在 Windows PowerShell 中,.NET 字符串被转码为 ASCII(!),导致非 ASCII 范围字符丢失 - 它们被转码为文字 ?
在 PowerShell (Core) 中,通过转码为 UTF-8 可以避免该问题。
System.BitConverter.ToString
失败,因为代码中的 $bytes
本身不是字节数组 ([byte[]]
),只是它的 .Bytes
属性 值是(但不包含感兴趣的值)。
也就是说,您并不是要将字节重新转换为 字符串,而是要将字节直接转换为 Base64 编码,如上所示。
我正在尝试在 PowerShell 中复制以下 Python 片段的功能:
allowed_mac_separators = [':', '-', '.']
for sep in allowed_mac_separators:
if sep in mac_address:
test = codecs.decode(mac_address.replace(sep, ''), 'hex')
b64_mac_address = codecs.encode(test, 'base64')
address = codecs.decode(b64_mac_address, 'utf-8').rstrip()
它接受一个MAC地址,删除分隔符,将其转换为十六进制,然后是base64。 (我没有编写 Python 函数,无法控制它或它如何工作。)
例如,MAC 地址 AA:BB:CC:DD:E2:00
将被转换为 AABBCCDDE200
,然后是 b'\xaa\xbb\xcc\xdd\xe2\x00'
,最后作为输出 b'qrvM3eIA'
。我尝试做类似的事情:
$bytes = 'AABBCCDDE200' | Format-Hex
[System.BitConverter]::ToString($bytes);
但这会产生 MethodException: Cannot find an overload for "ToString" and the argument count: "1".
,我不太确定它在寻找什么。我发现的所有使用该调用的示例都只有一个参数。这有效:
[System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes('AABBCCDDE200'))
但显然不会先将其转换为十六进制,因此会产生不正确的结果。感谢任何帮助。
# Remove everything except word characters from the string.
# In effect, this removes any punctuation ('-', ':', '.')
$sanitizedHexStr = 'AA:BB:CC:DD:E2:00' -replace '\W'
# Convert all hex-digit pairs in the string to an array of bytes.
$bytes = [byte[]] -split ($sanitizedHexStr -replace '..', '0x$& ')
# Get the Base64 encoding of the byte array.
[System.Convert]::ToBase64String($bytes)
有关用于创建 $bytes
数组的技术的说明,以及更简单的 PowerShell(核心)7.1+ / .NET 5+ 替代方案(简而言之:[System.Convert]::FromHexString('AABBCCDDE200')
),参见
至于你试过的:
Format-Hex
不是return字节数组(直接),它的主要目的是可视化 十六进制格式的输入数据对于人类观察者。
一般来说,Format-*
cmdlet 输出对象的唯一目的是向 PowerShell 的输出格式化系统提供 格式化指令 - 请参阅 this answer。简而言之:只使用 Format-*
cmdlet 来格式化数据 以供显示 ,永远不要用于后续 程序化处理 .
也就是说,在 Format-Hex
的特定情况下,输出对象 的类型 [Microsoft.PowerShell.Commands.ByteCollection]
, do contain useful data, and do contain the bytes of the transcoded characters of input strings .Bytes
property, as Cpt.Whale 指出。
但是,$bytes = ($sanitizedHexStr | Format-Hex).Bytes
将 不适用于您的情况,因为您将有效地获得反映 ASCII 代码点 [=91] 的字节值=] 等字符 A
(见下文) - 而你需要的是将这些字符解释为 十六进制数字 .
但即使在一般情况下我建议不要依赖Format-Hex
进行到字节数组的转换:
如前所述,
Format-*
cmdlet 的目的是产生 for-display 输出,而不是 data,值得观察这个区别,尽管有这个例外——输出对象的类型可以被认为是一个实现细节。Format-Hex
根据首先应用 固定字符转码 将字符串转换为字节(例如,您无法获得.NET 字符串 原样,基于 UTF-16 代码单元),并且 之间的固定转码 Windows PowerShell 和 PowerShell(核心):在 Windows PowerShell 中,.NET 字符串被转码为 ASCII(!),导致非 ASCII 范围字符丢失 - 它们被转码为文字
?
在 PowerShell (Core) 中,通过转码为 UTF-8 可以避免该问题。
System.BitConverter.ToString
失败,因为代码中的 $bytes
本身不是字节数组 ([byte[]]
),只是它的 .Bytes
属性 值是(但不包含感兴趣的值)。
也就是说,您并不是要将字节重新转换为 字符串,而是要将字节直接转换为 Base64 编码,如上所示。