下面的代码创建一个包含反向密码的哈希表。我试图在哈希表上执行查找,并返回结果。我正在尝试使用下面在powershell中创建的脚本解密提供给我的XML文件中的内容。
$translation = [ordered]@{}
$alpha = 'A'..'Z'
For($i=0; $i -lt 26; $i++)
{
$translation[$alpha[((((-$i + $offset) % 26) + 26) % 26)]] = $alpha[$i]
}
XML文件包含:
<?xml version="1.0" encoding="UTF-8"?>
<translate>
<caesar_cipher>
<offset>-7</offset>
<cipher>
RFGNCTAZITALFGB FG BZRRPBBOZIIV RFHEIPALGN AMP TQYTGRPQ EFXPCBMPII
TBBLNGHPGA
</cipher>
</caesar_cipher>
</translate>
有什么想法如何在哈希表中执行查找以解密XML文件中的消息,并输出到powershell?
答案 0 :(得分:3)
# The input XML.
$xml = @'
<?xml version="1.0" encoding="UTF-8"?>
<translate>
<caesar_cipher>
<offset>-7</offset>
<cipher>
RFGNCTAZITALFGB FG BZRRPBBOZIIV RFHEIPALGN AMP TQYTGRPQ EFXPCBMPII
TBBLNGHPGA
</cipher>
</caesar_cipher>
</translate>
'@
# Read the XML text into an XML DOM (XmlDocument).
$doc = [xml] $xml
# Extract the offset needed to build the translation hashtable.
$offset = $doc.translate.caesar_cipher.offset
# Build the translation hashtable, which maps a given [char] instance
# to a different [char] instance.
# (The hashtable doesn't strictly need to be *ordered*.)
$translation = [ordered] @{}
# NOTE: 'A'..'Z' only works in PowerShell *Core*.
# In *Windows PowerShell* you must use construct the array via *code points*,
# as shown in the next statement.
$alpha = [char[]] (65..90)
for($i=0; $i -lt 26; $i++) {
$translation[$alpha[((((-$i + $offset) % 26) + 26) % 26)]] = $alpha[$i]
}
# Add an entry to pass spaces through as-is.
$translation[[char] ' '] = [char] ' '
# Extract the text to be deciphered.
$cipherText = $doc.translate.caesar_cipher.cipher
# Translate the individual characters and reassemble them into a string.
-join $translation[[char[]] $cipherText]
以上结果:
CONGRATULATIONS ON SUCCESSFULLY COMPLETING THE ADVANCED POWERSHELL ASSIGNMENT
祝贺您成功地使我们为您做功课。
注意:
PowerShell自动提供方便的点符号(.
)以向下钻入到XML文档。
Select-Xml
cmdlet的XPath。 陷阱:PowerShell通常会根据需要自动自动将[char]
实例视为[string]
实例,但在哈希表查找中则不会:哈希表查找必须使用与键的数据类型相同的数据类型,这就是将$cipherText
强制转换为[char[]]
来查找[char]
实例的原因,以及为什么要添加上方空格的条目使用显式[char]
强制转换来定义键。
Windows PowerShell 仅支持范围操作符..
的数字端点,而PowerShell Core 也支持< em>字符。
答案 1 :(得分:1)
您的脚本有几个问题。首先,您生成的密码数学是错误的。您要从xml
拉出偏移量。您还希望在哈希中捕获空格字符,否则在执行查找时它将返回$null
。除非您已定义其他非字母字符,否则这都是正确的。解决此问题后,您所需要做的就是执行查找并将字符重新结合在一起。您可以通过在下面示例的PowerShell中传递数组来在字典中执行多次查找。
# initialize alpha and hash lookups
$alpha = 'A'..'Z'
$decipher = @{ ' ' = ' ' }
# load prerequisite variables
$xml = [xml]@'
<?xml version="1.0" encoding="UTF-8"?>
<translate>
<caesar_cipher>
<offset>-7</offset>
<cipher>
RFGNCTAZITALFGB FG BZRRPBBOZIIV RFHEIPALGN AMP TQYTGRPQ EFXPCBMPII TBBLNGHPGA
</cipher>
</caesar_cipher>
</translate>
'@
$offset = [int]$xml.translate.caesar_cipher.offset
$cipher = $xml.translate.caesar_cipher.cipher
# generate decipher table
0..($alpha.Length - 1) | % {$decipher["$($alpha[(-$_ + $offset) % $alpha.Length])"] = $alpha[$_]}
# perform lookups
-join $decipher[$cipher -split '']
答案 2 :(得分:0)
如TheIncorrigible1所建议,您可以使用XPath表达式//cipher/text()
选择所需的文本节点。
$xml = [xml](Get-Content path\to\file.xml)
$Ciphers = $xml.SelectNodes('//cipher/text()').InnerText
foreach($Cipher in $Ciphers){
Write-Host "Cipher text:`n$Cipher" -ForegroundColor Magenta
Write-Host "Decrypted text:`n$(-join ($Cipher.ToCharArray() |ForEach-Object {
# if it's in the set A..Z, translate
if($_ -in $alpha){
$_ = $translation[$_]
}
$_
}))" -ForegroundColor Green
}