Hashtable Lookup - PullRequest
       8

Hashtable Lookup

0 голосов
/ 21 ноября 2018

Приведенный ниже код создает хеш-таблицу, содержащую обратный шифр.Я пытаюсь предварительно выполнить поиск в хэш-таблице и вернуть результаты.Я пытаюсь расшифровать содержимое внутри предоставленного мне XML-файла с помощью сценария, который я создал ниже в powershell.

$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?

Ответы [ 3 ]

0 голосов
/ 22 ноября 2018

У вас есть пара проблем с вашим скриптом.Во-первых, ваше поколение математики шифра неверно.Вы хотите получить смещение от 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 '']
0 голосов
/ 22 ноября 2018
# 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] экземпляров ипочему добавление записи для пробелов выше использует явное приведение [char] для определения ключа.

  • WindowsPowerShell поддерживает только числовые конечные точки для .., оператора диапазона, тогда как PowerShell Core также поддерживает символов .

0 голосов
/ 22 ноября 2018

Как предполагает 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
}
...