我发现了多种在 Windows 上使用命令行对整个文件进行 Base64 编码的方法,但我似乎找不到一种使用命令行实用程序对“字符串”进行批量编码的简单方法。
如何做到这一点,例如在批处理文件中使用?
这是一个 PowerShell 单行代码,您可以从 cmd 控制台运行它,它将对字符串进行 Base64 编码。
powershell "[convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes(\"Hello world!\"))"
它可能不如 npocmaka 的解决方案那么快,但您可以 用它设置控制台宏。
doskey btoa=powershell "[convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes(\"$*\"))"
doskey atob=powershell "[Text.Encoding]::UTF8.GetString([convert]::FromBase64String(\"$*\"))"
btoa Hello world!
btoa This is fun.
btoa wheeeeee!
atob SGVsbG8gd29ybGQh
请注意,
doskey
不适用于批处理脚本——仅适用于控制台。 如果您想在批处理脚本中使用它,请创建一个函数。
@echo off
setlocal
call :btoa b64[0] "Hello world!"
call :btoa b64[1] "This is fun."
call :btoa b64[2] "wheeeeee!"
call :atob b64[3] SGVsbG8gd29ybGQh
set b64
goto :EOF
:btoa <var_to_set> <str>
for /f "delims=" %%I in (
'powershell "[convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes(\"%~2\"))"'
) do set "%~1=%%I"
goto :EOF
:atob <var_to_set> <str>
for /f "delims=" %%I in (
'powershell "[Text.Encoding]::UTF8.GetString([convert]::FromBase64String(\"%~2\"))"'
) do set "%~1=%%I"
goto :EOF
或者如果您更喜欢批处理 + JScript 混合:
@if (@CodeSection==@Batch) @then
@echo off & setlocal
call :btoa b64[0] "Hello world!"
call :btoa b64[1] "This is fun."
call :btoa b64[2] "wheeeeee!"
call :atob b64[3] SGVsbG8gd29ybGQh
set b64
goto :EOF
:btoa <var_to_set> <str>
:atob <var_to_set> <str>
for /f "delims=" %%I in ('cscript /nologo /e:JScript "%~f0" %0 "%~2"') do set "%~1=%%I"
goto :EOF
@end // end batch / begin JScript hybrid code
var htmlfile = WSH.CreateObject('htmlfile');
htmlfile.write('<meta http-equiv="x-ua-compatible" content="IE=10" />');
WSH.Echo(htmlfile.parentWindow[WSH.Arguments(0).substr(1)](WSH.Arguments(1)));
编辑:批处理+VBScript混合@Hackoo:
<!-- : batch portion
@echo off & setlocal
call :btoa b64[0] "Hello world!"
call :btoa b64[1] "This is fun."
call :btoa b64[2] "wheeeeee!"
call :atob b64[3] SGVsbG8gd29ybGQh
set b64
goto :EOF
:btoa <var_to_set> <str>
:atob <var_to_set> <str>
for /f "delims=" %%I in ('cscript /nologo "%~f0?.wsf" %0 "%~2"') do set "%~1=%%I"
goto :EOF
: VBScript -->
<job>
<script language="VBScript">
Set htmlfile = WSH.CreateObject("htmlfile")
htmlfile.write("<meta http-equiv='x-ua-compatible' content='IE=10' />")
if WSH.Arguments(0) = ":btoa" then
WScript.Echo htmlfile.parentWindow.btoa(WSH.Arguments(1))
else
WScript.Echo htmlfile.parentWindow.atob(WSH.Arguments(1))
end if
</script>
</job>
根据问题的评论,您可以使用certutil。例如,
certutil -encode raw.txt encoded.txt
或
certutil -f -encode raw.txt encoded.txt
-f
的意思是“强制覆盖”。否则,如果输出文件(上面的encoded.txt)已经存在,您将收到错误消息。
但是,这会将输出格式化为encoded.txt 文件,就好像它是证书PEM 文件一样,包含BEGIN 和END 行,并在最大字符处分割行。因此,您需要在批处理场景中进行进一步处理,如果字符串很长,还需要做一些额外的工作。
如果您安装了 OpenSSL for Windows,您可以使用它来编码字符串“Hello”:
echo | set /p="Hello" | openssl base64
| set /p=
是为了抑制echo通常输出的换行符。
这将产生与 bash 中的以下结果相同的结果:
echo -n 'Hello' | openssl base64
输出:
SGVsbG8=
这个脚本可以在XP及以上版本的每台机器上解码/编码base64字符串,无需安装.net或internet explorer 10/11。它甚至可以处理特殊的javascript转义符号:
// result is IkhlbGxvIg==
base64.bat -encode "\u0022Hello\u0022" -eval yes
// result is SGVsbG8=
base64.bat -encode "Hello"
这个接受一个参数 - 您想要编码为 Base 64 的字符串并打印结果(但至少需要安装 Internet Explorer 10):
@echo off
setlocal
set "string=%~1"
::echo %string%^|mshta.exe "%~f0"
for /f "delims=" %%# in ('echo %string%^|mshta.exe "%~f0"') do (
set b64=%%#
)
set b64
endlocal&exit /b %errorlevel%
<HTA:Application
ShowInTaskbar = no
WindowsState=Minimize
SysMenu=No
ShowInTaskbar=No
Caption=No
Border=Thin
>
<meta http-equiv="x-ua-compatible" content="ie=10" />
<script language="javascript" type="text/javascript">
window.visible=false;
window.resizeTo(1,1);
var fso= new ActiveXObject('Scripting.FileSystemObject').GetStandardStream(1);
var fso2= new ActiveXObject('Scripting.FileSystemObject').GetStandardStream(0);
var string=fso2.ReadLine();
var encodedString = btoa(string);
fso.Write(encodedString);
window.close();
</script>
这可以(技术上)完全在批处理中完成,方法是从批处理中创建加密\解密 VBS 脚本,可以使用要加密\解密其数据的变量的名称来调用该脚本。
注意:下面的脚本是一个独立的子程序。
用于密码或其他变量的混合批量 Vbs 加密器/解密器。 对存储在定义文件中的数据执行操作 - 不创建文件。
注意:vbs 中的文件扩展名与您保存密码/文本的文件类型相匹配。
要使用此程序,请使用您要设置的变量名称和要执行的偏移量来调用它。
但是您的主程序需要用户输入:
Set /p YourVariableName=
将输入存储到文件中
ECHO %YourVariableName%>YourSaveFile.txt
使用正偏移量(IE:+26)调用它来加密,并使用等效的负偏移量来解密。 (即:-26)
CALL "Insert Filepath To Encrypter.bat Here" YourVariableName +26
@ECHO OFF
REM :: Do NOT modify the variable names Below, DO INSERT the filepath you used to Store the Data Being Encrypted / Decrypted.
Set "VarName=%~1"
Set "offset=%~2"
Set "SaveLoc=Your Filepath Here"
<"%saveLoc%" (
Set /p encryptData=
)
(
ECHO Dim objFSO 'File System Object
ECHO Set objFSO = CreateObject("Scripting.FileSystemObject"^)
ECHO Dim objTS 'Text Stream Object
ECHO Const ForWriting = 2
ECHO Set objTS = objFSO.OpenTextFile("%SaveLoc%", ForWriting, True^)
ECHO objTS.Write(encode("%encryptData%"^)^)
ECHO wscript.sleep "1000"
ECHO function encode(s^)
ECHO For i = 1 To Len(s^)
ECHO newtxt = Mid( s, i, 1^)
ECHO newtxt = Chr(Asc(newtxt^) %offset%^)
ECHO coded = coded + (newtxt^)
ECHO Next
ECHO encode = coded
ECHO End function
ECHO objTS.Close(^)
ECHO Set bjFSO = Nothing 'Destroy the object.
ECHO Set objTS = Nothing 'Destroy the object.
) >%TEMP%\encrypter.vbs
START /wait %TEMP%\encrypter.vbs
DEL /Q "%TEMP%\encrypter.vbs"
GOTO :EOF
```
我必须对 @rojo 的 oneliner 进行一些修改才能使其工作。这适用于 Windows 11,无需安装任何其他软件:
[Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes(‘Hello world!’))
请注意,
不适用于批处理脚本——仅适用于控制台。如果您想在批处理脚本中使用它,请创建一个函数doskey
或使用宏:
@echo off
====SETLOCAL DisableDelayedExpansion EnableExtensions
REM Initalize
set ^"LF=^
%===EXPANDS TO NOTHING===%
"
::\n is an escaped LF + caret for line continuation
set ^"\n=^^^%LF%%LF%^%LF%%LF%^^"
REM MACRO
set ^"$b64.encode=FOR %%$ in (%%$ MainMacro) do if "%%$" == "MainMacro" (%\n%
^>nul %__APPDIR__%certutil.exe -f -encodehex args.tmp proc.tmp 0x40000001%\n%
type proc.tmp%\n%
echo(%\n%
del args.tmp proc.tmp%\n%
) 2^>nul ELSE ^<nul ^>args.tmp set/p="
REM EXAMPLES
%$b64.encode%"=I WILL FAIL (string cannot start with =)"
%$b64.encode%^" leading spaces/tabs will be stripped%\n%
but other characters are%\n%
OK!%\n%
;%%~dp$^&^|"""""""
字符串不得以
<SPACE> <TAB> <0xFF> =
SET /P
用于 写入而无需尾随 CRLF。
@dbenham提到了CERTUTIL
0x40000001
函数的类型
CryptBinaryToStringA
记录为:
不要将任何新行字符附加到编码字符串中。默认行为是使用回车/换行 (CR/LF) 对 (0x0D/0x0A) 来表示新行。
Windows Server 2003 和 Windows XP:不支持此值。
使用 Powershell 实现最佳、可靠。不过,文字长度有一些限制。
统一码
@echo off
set "string=Everything will be fine"
for /f "tokens=* delims=" %%i in ('powershell [convert]::ToBase64String([Text.Encoding]::Unicode.GetBytes("""%string%"""^)^)') do set "encoded=%%i"
echo %encoded%
UTF8
@echo off
set "string=Everything will be fine"
for /f "tokens=* delims=" %%i in ('powershell [convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes("""%string%"""^)^)') do set "encoded=%%i"
echo %encoded%
这对我有用,这不会通过 certutil 生成额外的行, 它将文件 data.txt 的内容转换为 base64 并将其保存到新文件 data.b64 .
certutil -encode data.txt tmp.b64 && findstr /v /c:- tmp.b64 > data.b64 && del tmp.b64
截至 2024 年,这适用于 Windows 11 上的编码:
"Hello, World!" | % { [Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($_)) }
这可用于解码:
"SGVsbG8sIFdvcmxkIQ==" | % { [System.Text.Encoding]::UTF8.GetString([Convert]::FromBase64String($_)) }
这种方法的优点是单行并首先提供字符串(与代码中间的某个位置相反)。此外,输出严格来说是字符串,这意味着没有多余的文本需要删除(与使用
cerutils
时相反)。