使用VBScript将Unicode字符串编码为Base64

时间:2016-10-18 15:31:42

标签: powershell unicode encoding vbscript

我想将powershell命令(字符串(get-date).date)编码为base64,以便通过powershell -encodedcommand xxx运行它。

使用标准的VBS方法(甚至是https://www.base64encode.org/),我得到KGdldC1kYXRlKS5kYXRl不能运行。

使用以下powershell脚本:

$bytes = [System.Text.Encoding]::Unicode.GetBytes($command)
$encodedCommand = [Convert]::ToBase64String($bytes)

我得到了KABnAGUAdAAtAGQAYQB0AGUAKQAuAGQAYQB0AGUA。差异似乎是该命令首先被编码为Unicode字节。

任何人都可以提供VBS函数来执行此操作或VBS等效的Unicode.GetBytes(),以便我们可以获得正确的字符串编码吗?

2 个答案:

答案 0 :(得分:3)

PowerShell仅接受 UTF-16 LE编码字符串的Base64编码及其
-EncodedCommand参数。
UTF-16 LE是Unicode代表[System.Text.Encoding]::Unicode的代码,它将绝大多数Unicode字符(代码点)编码为两个字节;它也是VBScript和PowerShell使用内部的字符串编码。

相比之下,大多数VBScript解决方案使用 - 字节ASCII编码,即使是其他值得称赞的Unicode识别https://www.base64encode.org/也只提供 UTF-8 的编码(使用其他语言的字符进行大多数单字节 - 西方语言编码。表示为2-4个字节)。

这是强大的基于UTF-16 LE的Base64编码解决方案

我发布了一个更模块化的变体,可选择支持 UTF-8 here;这两个位置的代码都建立在this great answer

之上

示例致电:

Base64EncodeUtf16Le("(get-date).date") ' -> "KABnAGUAdAAtAGQAYQB0AGUAKQAuAGQAYQB0AGUA"

来源代码:MC ND提供帮助以简化解决方案的提示。

' Base64-encodes the specified string using UTF-16 LE as the underlying text
' encoding.
Function Base64EncodeUtf16Le(ByVal sText)

    Dim bytesUtf16Le

    ' Create an aux. stream from which we can get a binary (byte array)
    ' representation of the input string in UTF-16 LE encoding. 
    With CreateObject("ADODB.Stream")
        ' Create a UTF 16-LE encoded text stream...
        .Type = 2  ' adTypeText
        .Charset = "utf-16le"
        .Open
        .WriteText sText
       ' ... and convert it to a binary stream, 
       ' so we can get the string as a byte array
        .Position = 0
        .Type = 1   ' adTypeBinary
        .Position = 2 ' Skip BOM
        bytesUtf16Le = .Read
        .Close
    End With 

    ' Use an aux. XML document with a Base64-encoded element.
    ' Assigning a byte stream (array) to .NodeTypedValue
    ' automatically performs Base64-encoding, whose result can then be accessed
    ' as the element's text.
    With CreateObject("Msxml2.DOMDocument").CreateElement("aux")
        .DataType = "bin.base64"
        .NodeTypedValue = bytesUtf16Le
        Base64EncodeUtf16Le = .Text
    End With

End Function

答案 1 :(得分:2)

我不确定这会满足您的所有需求,但至少它与您问题中指出的输出相匹配

Function ToBase64( ByVal text )
    Const adTypeText = 2
    Const adTypeBinary = 1

    ' Right pad each character with a null
    With New RegExp
        .Pattern = "(.)"
        .Global = True
        text = .Replace( text, "$1" & Chr(0) )
    End With

    ' Convert String to binary
    With WScript.CreateObject("ADODB.Stream")
        .Type = adTypeText
        .CharSet = "us-ascii"
        .Open
        .WriteText text
        .Position = 0
        .Type = adTypeBinary
        text = .Read
    End With

    ' Encode binary as Base64
    With WScript.CreateObject("Msxml2.DOMDocument.6.0").CreateElement("base64")
        .dataType = "bin.base64"
        .nodeTypedValue = text
        ToBase64 = Replace( .text, vbLf, "" )
    End With
End Function

WScript.Echo ToBase64("(get-date).date")

已编辑只是为了使我之前的代码适应enter image description here中的信息,您可以在其中找到powershell要求的详细信息以及有关代码如何工作的所有详细信息。

Function ToBase64( ByVal text )
    Const adTypeText = 2
    Const adTypeBinary = 1

    ' Change string encoding
    With WScript.CreateObject("ADODB.Stream")
        ' Convert input string to UTF-16 LE
        .Type = adTypeText
        .CharSet = "utf-16le"
        .Open
        .WriteText text
        ' Get binary representation of the string
        .Position = 0
        .Type = adTypeBinary
        .Position = 2 ' Skip BOM
        text = .Read
    End With

    ' Encode binary as Base64
    With WScript.CreateObject("Msxml2.DOMDocument.6.0").CreateElement("base64")
        .dataType = "bin.base64"
        .nodeTypedValue = text
        ToBase64 = Replace( .text, vbLf, "" )
    End With
End Function

WScript.Echo ToBase64("(get-date).date")