Reputation: 1987
I have found numerous ways to base64 encode whole files using the command-line on Windows, but I can't seem to find a simple way to batch encode just a "string" using a command-line utility.
How does one do this, for use in a batch file for example?
Upvotes: 71
Views: 250496
Reputation: 364
This works for encoding in Powershell 5.1.22621.2506.
"Hello, World!" | % { [Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($_)) }
This can be used for decoding:
"SGVsbG8sIFdvcmxkIQ==" | % { [System.Text.Encoding]::UTF8.GetString([Convert]::FromBase64String($_)) }
This approach has the advantages of being a one-liner and supplying the string first (opposed to somewhere in the middle of the code). Also, output is strictly the string, meaning there is no extra text to get rid of (opposed to when using cerutils
).
Upvotes: 1
Reputation: 70106
I had to modify the oneliner from @rojo a bit to make it work. This works on Windows 11 without any additional software installed:
[Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes(‘Hello world!’))
Upvotes: 4
Reputation: 61
This worked for me, this doesn't generate extra lines by certutil, it converts the content of the file data.txt to base64 and saves it to new file data.b64 .
certutil -encode data.txt tmp.b64 && findstr /v /c:- tmp.b64 > data.b64 && del tmp.b64
Upvotes: 0
Reputation: 724
Optimal, reliable ... with Powershell. However, there are some limitations in the length of the text.
Unicode
@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%
Upvotes: 1
Reputation: 841
Be advised that
doskey
doesn't work in batch scripts -- only the console. If you want do use this in a batch script, make a function
or use a macro:
@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$^&^|"""""""
The string must not begin with <SPACE> <TAB> <0xFF> =
because SET /P
is used to write without trailing CRLF.
@dbenham mentioned the undocumented verbs of CERTUTIL
. The type 0x40000001
of the CryptBinaryToStringA
function is documented as:
Do not append any new line characters to the encoded string. The default behavior is to use a carriage return/line feed (CR/LF) pair (0x0D/0x0A) to represent a new line.
Windows Server 2003 and Windows XP: This value is not supported.
Upvotes: 1
Reputation: 2951
This can (technically) be done entirely within Batch, By Creating an encryption\decryption VBS script from within batch that can be called with the name of the Variable whose Data you wish to encrypt\decrypt.
Note: The below scipt is an Independant Subprogram.
Hybrid Batch Vbs Encrypter / Decrypter for passwords or other variables. Performs the action on data stored in the defined file - does not create the file.
Note: file extension in vbs to match the filetype you save password/text to.
To use this program Call it with the name of the Variable you wish to set and the offset to perform.
However your Main program takes user input:
Set /p YourVariableName=
Store the Input to a File
ECHO %YourVariableName%>YourSaveFile.txt
Call it with a positive offset (IE: +26) to encrypt, and an equivalent Negative offset to Decrypt. (IE: -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
```
Upvotes: 2
Reputation: 24427
If you have OpenSSL for Windows installed you can use this to encode the string "Hello":
echo | set /p="Hello" | openssl base64
The | set /p=
is to suppress the newline that echo usually outputs.
This will produce the same result as the following in bash:
echo -n 'Hello' | openssl base64
Output:
SGVsbG8=
Upvotes: 23
Reputation: 24476
Here's a PowerShell one-liner you can run from a cmd console that'll Base64 encode a string.
powershell "[convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes(\"Hello world!\"))"
It's probably not as fast as npocmaka's solution, but you could set a console macro with it.
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
Be advised that doskey
doesn't work in batch scripts -- only the console. If you want do use this in a batch script, make a function.
@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
Or if you'd prefer a batch + JScript hybrid:
@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)));
Edit: batch + VBScript hybrid for @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>
Upvotes: 70
Reputation: 57272
This script can decode/encode base64 strings on every machine from XP and above without requiring installed .net or internet explorer 10/11.It even can handle special javascript escaped symbols:
// result is IkhlbGxvIg==
base64.bat -encode "\u0022Hello\u0022" -eval yes
// result is SGVsbG8=
base64.bat -encode "Hello"
This one accepts a single argument - the string you want to encode to base 64 and prints the result (but requires at least internet explorer 10 installed):
@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>
Upvotes: 12
Reputation: 12685
According to the comments on the question, you can use certutil. e.g.,
certutil -encode raw.txt encoded.txt
or
certutil -f -encode raw.txt encoded.txt
The -f
means "force overwrite". Otherwise you will get an error if the output file (encoded.txt above) already exists.
However, this will format the output into the encoded.txt file as if it were a certificate PEM file, complete with BEGIN and END lines, and split lines at the character max. So you would need to do further processing in a batch scenario, and a bit of extra work if the strings are long at all.
Upvotes: 58