2016-10-18 2 views
1

Я хочу закодировать команду powershell (строка (get-date).date) на base64, чтобы запустить ее через powershell -encodedcommand xxx.Кодировать строку Unicode на Base64 с VBScript

Использование стандартных методов VBS (или даже https://www.base64encode.org/) Я получаю KGdldC1kYXRlKS5kYXRl, который не работает.

Используя следующий Powershell скрипт:

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

я получаю KABnAGUAdAAtAGQAYQB0AGUAKQAuAGQAYQB0AGUA, который работает. Разница заключается в том, что команда сначала кодируется как байты Unicode.

Может ли кто-нибудь предоставить функцию VBS, которая делает это или эквивалент VBS Unicode.GetBytes(), чтобы мы могли получить нужную строку в кодировке?

ответ

3

PowerShell принимает только Base64 кодировки UTF-16 LE-закодированных строк с его параметром
-EncodedCommand.
UTF-16 LE - это то, что Unicode означает в [System.Text.Encoding]::Unicode, и он кодирует подавляющее большинство символов Юникода (кодовые точки) как два байтов каждый; это также строковая кодировка, используемая внутренне как VBScript, так и PowerShell.

В противоположности этому, большинство VBScript решений там использовать одиночную -байт кодировки ASCII, и даже в противном случае похвально Юникод https://www.base64encode.org/ только предлагает UTF-8 основанного кодирования (которое является главным-однобайтным -for-Western-языки с символами других языков, представленными как 2-4 байта).

Вот надежное решение для кодирования Base64 UTF-16 на основе LE.

Я отправил более модульный вариант, который опционально поддерживает UTF-8here; код в обоих местоположениях строится на 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

Great !.Я тестировал, но я пропустил опцию 'utf-16le'. Я адаптировал свой код к вашей информации, но у меня есть сомнения: почему два объекта adodb.stream? Есть ли какой-нибудь случай, когда решение с только одним может потерпеть неудачу? Есть ли улучшение в использовании двух экземпляров? –

+1

@MCND D'oh! Спасибо за это, я обновил свой ответ - 1 поток вполне достаточен; комбинация старого кода и ошибки при экспериментировании с одним потоком заставила меня ошибочно убедиться, что необходимы 2 потока. – mklement0

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") 
Смежные вопросы