【问题标题】:Encode Unicode String to Base64 with VBScript使用 VBScript 将 Unicode 字符串编码为 Base64
【发布时间】:2017-02-27 23:15:16
【问题描述】:

我想将一个 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 函数或 Unicode.GetBytes() 的 VBS 等效函数,以便我们可以得到正确的字符串编码?

【问题讨论】:

    标签: powershell unicode encoding vbscript


    【解决方案1】:

    PowerShell 仅接受带有
    -EncodedCommand 参数的 UTF-16 LE 编码字符串的 Base64 编码。
    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
    

    【讨论】:

    • 太棒了!我正在测试,但我错过了utf-16le 选项。我已经根据您的信息调整了我的代码,但我有一个疑问:为什么有两个 adodb.stream 对象?是否存在只有一个解决方案可能失败的情况?使用两个实例有什么改进吗?
    • @MCND 哦!谢谢你,我已经更新了我的答案——1个流就足够了;旧代码和在尝试单个流时出错的组合让我错误地认为需要 2 个流。
    【解决方案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")
    

    编辑只是为了使我以前的代码适应mklement0 answer 中的信息,您可以在其中找到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")
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-03-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-28
      • 1970-01-01
      • 2011-10-26
      相关资源
      最近更新 更多