Decoding base64 in batch
Asked Answered
P

2

95

I am trying to make an installer using batch. Of course, an installer needs to consist of files that will be installed, so I'm thinking of encoding the files in base64, and simply decode them and write them to their destination.

Of course, my work would be very easy if Windows had something like the base64 tool that Linux boxes contain. However, since it's simply not there, is there any way to decode base64 content completely using batch files? And how would I accomplish this?

Any help is appreciated.

(It's just an experiment, so I'm not worried about inefficiency and the like.)

Polyhydroxy answered 5/6, 2013 at 17:2 Comment(2)
Also check this out: f2ko.de/en/b64.phpHitchcock
This comment was my favorite answer, that program is much more like a Linux experience.Hormonal
M
184

Actually Windows does have a utility that encodes and decodes base64 - CERTUTIL

I'm not sure what version of Windows introduced this command.

To encode a file:

certutil -encode inputFileName encodedOutputFileName

To decode a file:

certutil -decode encodedInputFileName decodedOutputFileName

There are a number of available verbs and options available to CERTUTIL.

To get a list of nearly all available verbs:

certutil -?

To get help on a particular verb (-encode for example):

certutil -encode -?

To get complete help for nearly all verbs:

certutil -v -?

Mysteriously, the -encodehex verb is not listed with certutil -? or certutil -v -?. But it is described using certutil -encodehex -?. It is another handy function :-)

Update

Regarding David Morales' comment, there is a poorly documented type option to the -encodehex verb that allows creation of base64 strings without header or footer lines.

certutil [Options] -encodehex inFile outFile [type]

A type of 1 will yield base64 without the header or footer lines.

See https://www.dostips.com/forum/viewtopic.php?f=3&t=8521#p56536 for a brief listing of the available type formats. And for a more in depth look at the available formats, see https://www.dostips.com/forum/viewtopic.php?f=3&t=8521#p57918.

Not investigated, but the -decodehex verb also has an optional trailing type argument.

Motel answered 5/6, 2013 at 17:55 Comment(16)
Certutil has been around since at least Windows Server 2003.Boland
I would have given some good odds that "base64 in batch" was the most desperate thing I ever entered in a search engineConifer
@DavidRuhmann - Indeed, however, FWIW, the 2003 binary could be installed and used on Windows 2000Basinger
running certutil -encode inputFileName encodedOutputFileName generates a base64 string enclosed by "-----BEGIN CERTIFICATE-----" and "-----END CERTIFICATE-----" so you can't directly decode the file after it is produced.Tearoom
@DavidMorales - Not true! Did you try it? The -DECODE command works just fine with the header and footer in place. I'm not sure about the exact rules, but CERTUTIL -DECODE is very forgiving about the format of the encoded source.Motel
@Motel I didn't try to decode using certutil but other decoders will fail with incorrect padding errors because of those 2 lines (which I did try).Tearoom
Fair enough, but I should think an installer for Windows should use native WIndows tools - ie CERTUTIL. But it is good that people understand there is extra info in the -ENCODE output. It is very easy to eliminate the header and footer lines, if desired, via findstr /v /c:- certutilOutput.txt >cleanOutput.txt.Motel
IMHO certutil is broken. In my case it works for small files but I have tried it with 90MB files and the result is: CertUtil: -encodehex command FAILED: 0x80070216 (WIN32: 534) CertUtil: Arithmetic result exceeded 32 bitsArthurarthurian
@AndrzejMartyna - it's not that it's broken, but there is a maximum input file size of 74472684 bytes.King
@SomethingDark, thanks! this is a valuable information but I wonder where have you find this limit? I will stick with my opinion that certutil is broken because (1) the limitation should be documented clearly to the user or (2) there should be no limitation.Arthurarthurian
@AndrzejMartyna - I agree that there should be no limit :) I was stress-testing a script I wrote that included a file converted to base64, and I needed to know how big the file could be, so I used good old-fashioned brute force to test progressively larger files until the script broke.King
@SomethingDark, I highly appreciate your approach! It is the only way to be sure how sth works. Saying "broken" I have also meant that you cannot trust such tool - you start using this but one day or another the limitation will hunt you and you are left without an alternative :(Arthurarthurian
Cool. Now I can transfer self-extracting .exe-files over the clipboard via Citrix, at least in chunks of 70 Megabytes ;)Danica
@RadagasttheBrown - No. It only processes files.Motel
Is there a way to store the resulting base64 to the clipboard instead of generating the file?Unemployment
@ArchieG.Quiñones - No, CERTUTIL cannot work directly with stdin or stdout, so there is no built in way to pipe the result to CLIP. But you can write a batch script that writes to a temporary file, TYPE the temp file and pipe the output to CLIP, and then delete the temp file.Motel
J
5

Here's a batch file, called base64encode.bat, that encodes base64.

@echo off
if not "%1" == "" goto :arg1exists
echo usage: base64encode input-file [output-file]
goto :eof
:arg1exists
set base64out=%2
if "%base64out%" == "" set base64out=con 
(
  set base64tmp=base64.tmp
  certutil -encode "%1" %base64tmp% > nul
  findstr /v /c:- %base64tmp%
  erase %base64tmp%
) > %base64out%
Jerricajerrie answered 30/1, 2017 at 19:55 Comment(2)
This script will work better if you add setlocal enabledelayedexpansion and use !base64tmp! inside the (...). Otherwise the value is determined when the (...) sequence is read in, not when it is executed.Emancipation
a much simpler solution, without having to deal with the headers: https://mcmap.net/q/225090/-cmd-batch-encode-file-to-base-64-and-trim-characters-and-new-lineCopra

© 2022 - 2024 — McMap. All rights reserved.