【问题标题】:PowerShell hex to string conversionPowerShell 十六进制到字符串的转换
【发布时间】:2013-06-21 07:28:34
【问题描述】:

需要帮助将文本文件中包含的所有十六进制字符转换为字符串或 ASCII。十六进制字符以

的标准格式出现
user1 domain1 7374726f6e6770617373776f7264403130                                               
user2 domain2 7374726f6e6770617373776f7264403120

转换后应该显示为

user1 domain1 strongpassword@10

文本文件包含多个密码,全部排成一行

【问题讨论】:

    标签: powershell


    【解决方案1】:
    $pass=""
    $t="7374726f6e6770617373776f7264403130"
    $t -split '(.{2})' |%{ if ($_ -ne "") { $pass+=[CHAR]([CONVERT]::toint16("$_",16))  }}
    write host $pass
    

    【讨论】:

      【解决方案2】:

      像这样:

      $h =  7374726f6e6770617373776f7264403130
      
      -join ($h -split '(..)' | ? { $_ } | % { [char][convert]::ToUInt32($_,16) })
      

      【讨论】:

      • 文本文件包含多个密码,都排成一行,所以我想我们不能定义这样的变量
      【解决方案3】:
      $IN="SOME LONG CRAZY STRING TO CONVERT TO HEX"
      
      $HEX = $(($IN | Format-Hex).ToString().Split("`n")).ForEach({ $_.remove(0,11) -replace '[ ]{2,}.*$','' }).Split() -join ''
      
      Write-Host $HEX
      
      $OUT = $($HEX -split '(.{2})').ForEach({ if ($_ -ne "") { [CHAR]([CONVERT]::toint16("$_",16)) } }) -join ''
      
      Write-Host $OUT
      

      【讨论】:

      • 通常最好解释一个解决方案,而不是仅仅发布一些匿名代码行。你可以阅读How do I write a good answer,也可以阅读Explaining entirely code-based answers
      • 显然我缺乏解释得罪了某人。这将使用 Format-Hex 将文本字符串 $IN 转换为十六进制,然后解析并连接输出,因此您的结果是一个十六进制值 $HEX 的字符串。然后我将十六进制字符串 $HEX 转换回文本 $OUT.
      【解决方案4】:
      Get-Content file.txt | Foreach-Object{
      
          $user,$domain,$pass = $_.Split()
      
          $pass = for($i=0; $i -lt $pass.length; $i+=2)
          {
             [char][int]::Parse($pass.substring($i,2),'HexNumber')
          }
      
          $user,$domain,(-join $pass) -join ' '
      }
      

      【讨论】:

        【解决方案5】:

        以这个为例说明如何做到这一点:

        $text = 'user1 domain1 7374726f6e6770617373776f7264403130'
        $p = [Regex]::Match($text, '\w+$').Value
        $pass = ((0..(($p.length - 1) / 2) | % {[Char]([Convert]::toint16($p.SubString($_ * 2, 2), 16))}) -Join '')
        $text = $text -Replace '\w+$', $pass
        $text
        

        【讨论】:

          【解决方案6】:

          第一个响应是唯一返回包含用户、域、十六进制解码密码的行。

          第二个响应是最优雅的 Perl。

          这是两者的结合:

          [regex]$regEx = '(\S+)$';
          $scriptBlock = { param ($match); -join ( $match.Groups[1].Value -split '(..)' | ? { $_; } | % { [Char]( [Convert]::ToInt16($_, 16) ); } ); }
          Get-Content file.txt | % { $regEx.Replace($_, $scriptBlock); }
          

          脚本块可以被格式化以提高可读性,而不是简洁/类似 Perl 的混淆。 :)

          $scriptBlock = { 
              param ($match); 
              -join ( 
                  $match.Groups[1].Value -split '(..)' | ? { $_; } | % { 
                      [Char]( [Convert]::ToInt16($_, 16) ); 
                  } 
              ); 
          };
          

          【讨论】:

            【解决方案7】:

            另一种选择。这样做的好处是为您提供了一个可以使用 Format-Table 查看或使用 Export-Csv 导出的对象。此外,这里的 ConvertForm-Hexadecimal 实现非常快,即使处理非常大的字符串也能很好地工作。

            function ConvertFrom-Hexadecimal([string] $hexString)
            {
                [byte[]] $data = @()
            
                if ([string]::IsNullOrEmpty($hexString) -eq $true -or $hexString.Length % 2 -ne 0)
                {
                    throw New-Object FormatException("Hexadecimal string must not be empty and must contain an even number of digits to be valid.");
                }
            
                $hexString = $hexString.ToUpperInvariant()
                $data = New-Object byte[] -ArgumentList ($hexString.Length / 2)
            
                for ([int] $index = 0; $index -lt $hexString.Length; $index += 2)
                {
                    [int] $highDigitValue = if ($hexString[$index] -le ([char] '9')) { $hexString[$index] - ([char] '0') } else { $hexString[$index] - ([char] 'A') + 10 }
                    [int] $lowDigitValue = if ($hexString[$index + 1] -le ([char] '9')) { $hexString[$index + 1] - ([char] '0') } else { $hexString[$index + 1] - ([char] 'A') + 10 }
            
                    if ($highDigitValue -lt 0 -or $lowDigitValue -lt 0 -or $highDigitValue -gt 15 -or $lowDigitValue -gt 15)
                    {
                        throw New-Object FormatException("An invalid digit was encountered. Valid hexadecimal digits are 0-9 and A-F.")
                    }
                    else
                    {
                        [byte] $value = [byte](($highDigitValue -shl 4) -bor ($lowDigitValue -band 0x0F))
                        $data[$index / 2] = $value;
                    }
                }
            
                return ,$data
            }
            
            $fileName = '.\testfile.txt'
            
            $passwordColumn = @{ name = 'Password'; expression = { $bytes = ConvertFrom-Hexadecimal $_.EncodedPassword; [System.Text.Encoding]::ASCII.GetString($bytes); } }
            $users = Import-Csv -Delimiter ' ' -Header User, Domain, EncodedPassword -Path $fileName | Select *, $passwordColumn
            $users | ft -AutoSize
            

            【讨论】:

              猜你喜欢
              • 2012-01-24
              • 2019-07-30
              • 2020-11-07
              • 1970-01-01
              • 2013-09-05
              • 2021-03-19
              • 2016-12-27
              相关资源
              最近更新 更多