为何传入机器名字符串与调用[Environment]::MachineName.ToString()输出不同?
传入机器名字符串与[Environment]::MachineName得到不同SHA256哈希值的问题及解决
为什么手动传入机器名字符串和使用[Environment]::MachineName.ToString()会得到不同的SHA256哈希输出?我需要让二者被识别为相同内容,输出相同的哈希值。
运行下方的Set-Value函数时,第一次调用填入带引号的机器名,第二次省略该参数,就能看到两种不同的输出:
function Set-Value() { param ( [Parameter()] [string] $p_ranNumber, # required [Parameter()] [string] $p_machineName # not required ) $envMachineName = [Environment]::MachineName; $displayOnly = $false; if ($p_machineName -eq "") { $p_machineName = $envMachineName; } else { $displayOnly = $true; } $combinedString = "$($p_ranNumber)`:$($p_machineName)" $bytes = [System.Text.Encoding]::UTF8.GetBytes($combinedString); $sha256 = [System.Security.Cryptography.SHA256]::Create(); $hashBytes = $sha256.ComputeHash($bytes); $hexString = ($hashBytes | ForEach-Object { $_.ToString("X2") }) -join ''; if ($displayOnly -eq $true) { Write-Host "$($p_ranNumber)_$($hexString)"; } else { Write-Host "$($p_ranNumber)_$($hexString)"; } } Set-Value -p_ranNumber "123456" -p_machineName "[machine name string]"; Set-Value -p_ranNumber "123456";
问题原因
- 内容格式不统一:手动输入的机器名可能包含前后空格、全角空白字符,或者大小写与
[Environment]::MachineName返回的系统标准机器名不一致,导致字符串实际内容不同。 - 空值判断逻辑漏洞:原函数用
$p_machineName -eq ""判断空值,若传入的是$null或[string]::Empty,处理逻辑可能不符合预期,但核心问题还是输入内容与系统值的差异。 - 隐形编码差异:手动复制的字符串可能携带BOM(字节顺序标记)或其他隐形编码字符,导致转换为UTF8字节数组时与系统值不同。
解决方法
通过标准化处理输入的机器名字符串,使其与[Environment]::MachineName的输出对齐,即可得到相同的哈希值:
修改后的函数示例
function Set-Value() { param ( [Parameter(Mandatory=$true)] [string] $p_ranNumber, [Parameter()] [string] $p_machineName ) # 标准化系统机器名:去除空白、统一大写 $envMachineName = [Environment]::MachineName.Trim().ToUpper() $displayOnly = $false; # 更严谨的空值判断 if ([string]::IsNullOrWhiteSpace($p_machineName)) { $p_machineName = $envMachineName; } else { # 标准化传入的机器名,和系统值格式对齐 $p_machineName = $p_machineName.Trim().ToUpper() $displayOnly = $true; } $combinedString = "$p_ranNumber`:$p_machineName" $bytes = [System.Text.Encoding]::UTF8.GetBytes($combinedString); $sha256 = [System.Security.Cryptography.SHA256]::Create(); $hashBytes = $sha256.ComputeHash($bytes); $hexString = ($hashBytes | ForEach-Object { $_.ToString("X2") }) -join ''; Write-Host "$p_ranNumber`_$hexString" } # 调用示例 Set-Value -p_ranNumber "123456" -p_machineName "YourMachineName"; Set-Value -p_ranNumber "123456";
额外排查技巧
如果仍有差异,可以添加日志查看字符串的字节细节,定位隐形字符:
# 输出字符串字节长度,快速判断是否有隐藏内容 Write-Host "传入机器名字节数: $([System.Text.Encoding]::UTF8.GetBytes($p_machineName).Length)" Write-Host "系统机器名字节数: $([System.Text.Encoding]::UTF8.GetBytes($envMachineName).Length)"
内容的提问来源于stack exchange,提问作者Bbb
相关产品推荐
相关产品推荐

