【问题标题】:Hashtable Lookup哈希表查找
【发布时间】:2018-11-21 20:53:32
【问题描述】:

下面的代码创建了一个包含反向密码的哈希表。我正在尝试对哈希表进行查找,并返回结果。我正在尝试使用我在下面在 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?

【问题讨论】:

  • the question here 的副本
  • 请不要通过破坏您的帖子为人们增加工作量。通过在 Stack Exchange (SE) 网络上发帖,您已在 CC BY-SA 3.0 license 下授予 SE 分发该内容的不可撤销权利(即无论您未来的选择如何)。根据 SE 政策,帖子的非破坏版本是分发的版本。因此,任何破坏行为都将被撤销。

标签: powershell hashtable caesar-cipher


【解决方案1】:
# 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 文档

  • 陷阱:PowerShell 通常自动根据需要将[char] 实例视为[string] 实例,但在哈希表查找的情况下则不然:哈希表查找必须使用与键的数据类型相同的数据类型,这就是为什么$cipherText 被强制转换为[char[]] 以查找[char] 实例以及为什么添加上面的空格条目使用显式@987654333 @cast 定义键。

  • Windows PowerShell 仅支持范围运算符 ..numerical 端点,而 PowerShell Core 也支持 字符

【讨论】:

  • 很好,没想到你可以[char[]]$string
  • @bear443:听起来您使用的是 Windows PowerShell,而不是 PowerShell Core。只有后者支持使用 characters.. 来创建字符范围。请参阅我的更新以了解如何在 Windows PowerShell 中执行此操作。更新后的代码现在应该可以在 Windows PowerShell 和 PowerShell Core 上运行。
  • @TheIncorrigible1:是的,它实际上与$string.ToCharArray() 相同,但我更喜欢[char[]],因为它更符合PowerShell 习惯。在性能方面,几乎没有区别。
【解决方案2】:

您的脚本存在一些问题。首先,您这一代的密码数学是错误的。您想从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 '']

【讨论】:

  • 我经常收到这个空错误。有没有办法在像 mklement0 评论的脚本中使用它?
  • @bear443 我使用它没有任何错误。听起来像是用户错误。
【解决方案3】:

正如 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
}

【讨论】:

    猜你喜欢
    • 2016-04-03
    • 1970-01-01
    • 2013-04-03
    • 1970-01-01
    • 1970-01-01
    • 2010-11-26
    • 2012-07-02
    • 1970-01-01
    • 2011-11-11
    相关资源
    最近更新 更多