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?
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>
object.methodname and object["methodname"], but VBScript seems not to allow that second convention without hackish workarounds like eval(). You could use WSH.Echo eval("htmlfile.parentWindow." & Mid(WSH.Arguments(0), 2) & "(""" & WSH.Arguments(1) & """)") in place of that 5-line if block, but I don't like using eval().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.
-decode verb which can decode files from base64 to text.certutil -encodehex -f raw.txt encoded.txt 0x40000001If 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=
openssl command to decrypt, in that case? I tried echo | set /p="SGVsbG8=" | openssl enc -a -d, it outputs nothingecho SGVsbG8= | openssl base64 -d works for me. Seems to just ignore the newlineecho | set /p="Hello" | openssl base64 should be echo set /p="Hello" | openssl base64 to output the encoded string.c2V0IC9wPSJIZWxsbyIgDQo= which is the encoding of set /p="Hello" instead of the encoding of Hello which is SGVsbG8=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>
window.btoa and window.atob methods were introduced in IE 10. Your script would be compatible with earlier versions of Windows if you replace ie=edge with ie=10.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
```
Be advised that
doskeydoesn'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.
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%
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).
create a simple text file insert the encoded data into it and use the following command
certutil -decode 1.txt 2.txt
the decoded text will be saved in 2.txt
certutil.exe is suggested already in a comment below the question and in multiple answers. Please read first everything on a Stack Overflow page before writing an answer to a question to avoid adding redundant information.
CertUtil.exe, a native tool of Windows with many useful verbs? for instance,CertUtil -encodeandCertUtil -decodeencode/decode a file to/from Base64; (also helpful:CertUtil -hashfile [{SHA1|MD5}]computes a hash value over a file...) - with a temporary file you can also process strings...