Question

I am fairly new to writing scripts in batch, and I am looking for an effective way to make an ASCII to hex converter. I tried searching for some tutorials online, but the only things I found were using Perl or other scripting languages.

So my real question is what languages can I use inside of my batch file? What is the standard language? What's compatible? I know I should really invest in a scripting book or scripting class, but this has just been one of the many side-projects I have been working on here at my company, and haven't had too much time to become an expert. Thank you in advance for any information you can provide, and help clear up my confusion!!

EDIT

Ok so it looks like the best way is to use one of the support scripting tools like VBscript, Jscript or powershell. Does anyone know which approach would be best for my situation.

Basically I need to start out with asking for the part number that looks like this: "BL6A-19T508-NYL". I can do that with this.

SET /p "str1=Enter part number "

But from there which scripting support tool should I use? and how would I implement it to use my variable that I input?

From there I should probably output the Hex back into the same variable. in my case preferably without the spaces between the hex values. So i would like the part number BL6A-19T508-NY to convert to 424c36412d3139543530382d4e59

I'm not really understanding how I can

I found this powershell code on converting from ascii to hex

$a = "http://www.google.com";
$b = $a.ToCharArray();
Foreach ($element in $b) {$c = $c + " " + [System.String]::Format("{0:X2}", [System.Convert]::ToUInt32($element))}

I tried using the rules from this website http://learningpcs.blogspot.com/2009/07/powershell-string-to-hex-or-whatever.html to allow it to work in my batch file. This is what i got.

@echo off
SET /p "str1=Enter part number "
powershell.exe -command '$a = "BL6A-19T508-NYL";'
powershell.exe -command '$b = $a.ToCharArray();'
powershell.exe -command 'Foreach ($element in $b) {$c = $c + " " + [System.String]::Format("{0:X2}", [System.Convert]::ToUInt32($element))}'
powershell.exe -command '$c'
pause

I put my part number in, and added the pause to see what happens. All it does is

Screenshot of The codes output.

It doesn't quite work...

So my first step is to work on getting the converter to work as it should. And from there, work from the variable, and finally place the hex value back into the variable, or into a new variable.

I'm going to keep working on it, If anyone sees anything I could do, or something I am doing wrong, It would be much appreciated. Thank you all!!

Was it helpful?

Solution

Note - I began working on this answer when the question asked for a batch solution, before it was edited to ask for PowerShell.

This is a subject near and dear to my heart. (Actually, many subjects)

Embedding other scripting languages within batch

There are good strategies for embedding many scripting languages in batch. See js/vbs/html/hta hybrids and chimeras in cmd/bat.

Generally I think it is not a good idea to create hybrid code. Batch is quite limited in capabilities. Chances are good that if you can write a hybrid batch script that embeds another language, it would have been easier and more efficient to simply write the entire solution using the other scripting language.

But I think it is reasonable to create stand-alone hybrid batch utilities that tackle some of the limitations of batch. These utilities can be used to effectively extend the batch language for anyone that wants to continue to work in batch. Certainly 3rd party executeables can do the same thing, but many companies frown at introducing non-standard executeables, yet allow scripts.

Here are a couple hybrid utilities I have written:

  • REPL.BAT - Perform regular expression search and replace on stdin and write the result to stdout
  • getTimestamp.bat - Date and time formatter and computation engine

ASCII to hex converter using batch

This was one of the first batch projects I ever tackled. I succeeded in creating CHARLIB.BAT - a pure batch utility that includes str2Hex, a function that converts a string into a string of hexadecimal digits representing the ASCII code values. If you follow the link it will download a file named CHARLIB.BAT.TXT - simply rename the file to CHARLIB.BAT and it is ready to use. Run the script without any arguments to get help on how to use it.

Development of the utility can be followed at http://www.dostips.com/forum/viewtopic.php?f=3&t=1733

Here is a trivial example of usage:

@echo off
setlocal
set "str=Hello world!"
call charlib str2hex str hex
echo str=%str%
echo hex=%hex%

-- OUTPUT --

str=Hello world!
hex=48656C6C6F20776F726C6421

But CHARLIB.BAT has characters embedded within the script that do not post well on sites such as this.

I then created a macro version of two of the key functions at Batch macros to convert between ASCII code and character . This has two major enhancements:

  • It uses an advanced batch programming technique, Batch "macros" with arguments, to dramatically improve the performance

  • It uses embedded VBScript via WSF to generate the lookup maps so that the code can now be posted on sites such as this.

Below is an extended version that adds an @Str2Hex macro that I did not have at my original DosTips post:

charMacros.bat

<!-- : Begin batch script
@echo off
:: charMacros.bat
::
::   This script installs macros that can be used to interconvert between
::   numeric extended ASCII codes and character values.
::
::   The script defines the following variables:
::
::     @Str2Hex - A macro used to convert a string into a string of hex digit
::                pairs representing the ASCII codes in the string.
::
::     @asc - A macro used to convert a character into the decimal ASCII code
::
::     @ascHex - A macro used to convert a character into the hex ASCII codde
::
::     @chr - A macro used to convert a numeric ASCII code into a character
::
::     #LF - A variable containing a line feed character
::
::     #CR - A variable containing a carriage return character
::
::     #charMap - A variable used by the @asc macro
::
::     #asciiMap - A variable used by the @chr macro
::
::     #mapCodePage - The CHCP setting at the time the maps were loaded
::
::     \n - used for specifiying the end of line in a macro definition
::
:: Originally developed and posted by Dave Benham (with help from DosTips users) at
:: http://www.dostips.com/forum/viewtopic.php?f=3&t=4284

if "!" == "" >&2 echo ERROR: Delayed expansion must be disabled when loading %~nx0&exit /b 1

:: Define a Carriage Return string, only useable as !#CR!
for /f %%a in ('copy /Z "%~dpf0" nul') do set "#CR=%%a"

:: Define a Line Feed (newline) string (normally only used as !#LF!)
set #LF=^


:: Above 2 blank lines are required - do not remove

:: Define a newline with line continuation
set ^"\n=^^^%#LF%%#LF%^%#LF%%#LF%^^"

:: Define character maps used to interconvert between extended ASCII codes
:: and characters.
set "#charMap="
for /f "delims=" %%A in ('cscript //nologo "%~f0?.wsf"') do (
  if defined #charMap (set "#asciiMap=%%A") else set "#charMap= %%A"
)
for /f "delims=" %%A in ('chcp') do set "#mapCodePage=%%A"


:: %@Str2Hex%  StrVar  [RtnVar]
::
::   Converts the string within StrVar into a string of extended ASCII codes,
::   with each code represented as a pair of hexadecimal digits. The length of
::   the result will always be exactly twice the length of the original string.
::
::   Any character within the string that is not in the currently loaded code
::   page will be represented as 00.
::
::   The result is stored in RtnVar, or ECHOed if RtnVar is not specified.
::
::   The macro is safe to "call" regardless whether delayed expansion
::   is enabled or not.
::
::     StrVar = The name of a variable that contains the string
::              to be converted
::
::     RtnVar = The name of the variable used to store the result.
::
set @Str2Hex=for %%# in (1 2) do if %%#==2 (%\n%
for /f "eol= tokens=1,2 delims=, " %%a in ("!#args!") do (endlocal%\n%
  setlocal enableDelayedExpansion%\n%
  if defined %%~a (%\n%
    set "str=!%%~a!"%\n%
    set "s=!%%~a!"%\n%
    set "len=0"%\n%
    for %%P in (4096 2048 1024 512 256 128 64 32 16 8 4 2 1) do (%\n%
      if "!s:~%%P,1!" neq "" (%\n%
        set /a "len+=%%P"%\n%
        set "s=!s:~%%P!"%\n%
      )%\n%
    )%\n%
    set "rtn="%\n%
    for /l %%N in (0 1 !len!) do (%\n%
      set "chr=!str:~%%N,1!"%\n%
      set "hex="%\n%
      if "!chr!"=="=" set hex=3D%\n%
      if "!chr!"=="^!" set hex=21%\n%
      if "!chr!"=="!#lf!" set hex=0A%\n%
      if not defined hex for /f delims^^=^^ eol^^= %%c in ("!chr!!#CR!") do (%\n%
        set "test=!#asciiMap:*#%%c=!"%\n%
        if not "%%c"=="!test:~0,1!" set "test=!test:*#%%c=!"%\n%
        if "%%c"=="!test:~-0,1!" (set "hex=!test:~1,2!") else set "hex=00"%\n%
      )%\n%
      set "rtn=!rtn!!hex!"%\n%
    )%\n%
    for %%v in (!rtn!) do endlocal^&if "%%~b" neq "" (set "%%~b=%%v") else echo(%%v%\n%
  ) else endlocal%\n%
set "#args=")) else setlocal enableDelayedExpansion^&set #args=,


:: %@asc%  StrVar  Position  [RtnVar]
::
::   Converts a character into the extended ASCII code value.
::   The result is stored in RtnVar, or ECHOed if RtnVar is not specified.
::   A value of -1 is returned if the character is not in the currently loaded
::   code page. The macro is safe to "call" regardless whether delayed expansion
::   is enabled or not.
::
::     StrVar = The name of a variable that contains the character
::              to be converted
::
::     Position = The position of the character within the string
::                to be converted. 0 based.
::
::     RtnVar = The name of the variable used to store the result.
::
set @asc=for %%# in (1 2) do if %%#==2 (%\n%
for /f "eol= tokens=1-3 delims=, " %%a in ("!#args!") do (endlocal%\n%
  setlocal enableDelayedExpansion%\n%
  if defined %%~a (%\n%
    set "str=!%%~a!"%\n%
    set /a "n=%%~b" 2^>nul%\n%
    for %%N in (!n!) do set "chr=!str:~%%N,1!"%\n%
    if defined chr (%\n%
      set "rtn="%\n%
      if "!chr!"=="=" set rtn=61%\n%
      if "!chr!"=="^!" set rtn=33%\n%
      if "!chr!"=="!#lf!" set rtn=10%\n%
      if not defined rtn for /f delims^^=^^ eol^^= %%c in ("!chr!!#CR!") do (%\n%
        set "test=!#asciiMap:*#%%c=!"%\n%
        if not "%%c"=="!test:~0,1!" set "test=!test:*#%%c=!"%\n%
        if "%%c"=="!test:~-0,1!" (set /a "rtn=0x!test:~1,2!") else set "rtn=-1"%\n%
      )%\n%
    )%\n%
    for %%v in (!rtn!) do endlocal^&if "%%~c" neq "" (set "%%~c=%%v") else echo(%%v%\n%
  ) else endlocal%\n%
set "#args=")) else setlocal enableDelayedExpansion^&set #args=,


:: %@chr%  AsciiCode  [RtnVar]
::
::   Converts an extended ASCII code into the corresponding character.
::   The result is stored in RtnVar, or ECHOed if RtnVar is not specified.
::   The macro supports value 1 - 255. The value 0 is not supported.
::   The macro is safe to "call" regardless whether delayed expansion is
::   enabled or not.
::
::     AsciiCode - Any value from 1 to 255. The value can be expressed as any
::                 numeric expression supported by SET /A.
::
::     RtnVar - The name of the variable used to store the result
::
set @chr=for %%# in (1 2) do if %%#==2 (%\n%
for /f "eol= tokens=1,2 delims=, " %%a in ("!#args!") do (endlocal%\n%
  setlocal%\n%
  set "NotDelayed=!"%\n%
  setlocal EnableDelayedExpansion%\n%
  set "n=0"%\n%
  set /a "n=%%~a"%\n%
  if !n! gtr 255 set "n=0"%\n%
  if !n! gtr 0 (%\n%
    if !n! equ 10 (%\n%
      for %%C in ("!#LF!") do (%\n%
        endlocal^&endlocal%\n%
        if "%%~b" neq "" (set "%%~b=%%~C") else echo(%%~C%\n%
      )%\n%
    ) else (%\n%
      for %%N in (!n!) do set "c=!#charMap:~%%N,1!"%\n%
      if "!c!" equ "^!" if not defined NotDelayed set "c=^^^!"%\n%
      for /f delims^^=^^ eol^^= %%C in ("!c!!#CR!") do (%\n%
        endlocal^&endlocal%\n%
        if "%%~b" neq "" (set "%%~b=%%C") else echo(%%C%\n%
      )%\n%
    )%\n%
  ) else endlocal^&endlocal%\n%
set "#args=")) else setlocal enableDelayedExpansion^&set #args=,


:: %@ascHex%  StrVar  Position  [RtnVar]
::
::   Converts a character into the extended ASCII code hex value.
::   The result is stored in RtnVar, or ECHOed if RtnVar is not specified.
::   A value of -1 is returned if the character is not in the currently loaded
::   code page. The macro is safe to "call" regardless whether delayed expansion
::   is enabled or not.
::
::     StrVar = The name of a variable that contains the character
::              to be converted
::
::     Position = The position of the character within the string
::                to be converted. 0 based.
::
::     RtnVar = The name of the variable used to store the result.
::
set @ascHex=for %%# in (1 2) do if %%#==2 (%\n%
for /f "eol= tokens=1-3 delims=, " %%a in ("!#args!") do (endlocal%\n%
  setlocal enableDelayedExpansion%\n%
  if defined %%~a (%\n%
    set "str=!%%~a!"%\n%
    set /a "n=%%~b" 2^>nul%\n%
    for %%N in (!n!) do set "chr=!str:~%%N,1!"%\n%
    if defined chr (%\n%
      set "rtn="%\n%
      if "!chr!"=="=" set rtn=3D%\n%
      if "!chr!"=="^!" set rtn=21%\n%
      if "!chr!"=="!#lf!" set rtn=0A%\n%
      if not defined rtn for /f delims^^=^^ eol^^= %%c in ("!chr!!#CR!") do (%\n%
        set "test=!#asciiMap:*#%%c=!"%\n%
        if not "%%c"=="!test:~0,1!" set "test=!test:*#%%c=!"%\n%
        if "%%c"=="!test:~-0,1!" (set "rtn=!test:~1,2!") else set "rtn=-1"%\n%
      )%\n%
    )%\n%
    for %%v in (!rtn!) do endlocal^&if "%%~c" neq "" (set "%%~c=%%v") else echo(%%v%\n%
  ) else endlocal%\n%
set "#args=")) else setlocal enableDelayedExpansion^&set #args=,


exit /b 0


----- Begin wsf script --->
<job><script language="VBScript">
for i=1 to 255
  if i=10 then WScript.Stdout.Write " " else WScript.Stdout.Write chr(i)
next
WScript.Stdout.Write chr(10)+"#"
for i=1 to 255
  if i<>10 then WScript.Stdout.Write chr(i)+chr(i)+right("0"+hex(i),2)+"#"
next
</script></job>

The charMacros are designed to be "terminate and stay resident", meaning they only need to be loaded once, and then any number of batch scripts can take advantage of them.

Here is a simple example of how to use @Str2Hex:

@echo off
:: Load the charMacros if not already loaded. The macros are dependent on
:: the active code page, so if it has changed, then the macros are reloaded.
:: The macros are loaded prior to SETLOCAL so that the macros persist after
:: the script terminates
for /f "delims=" %%A in ('chcp') do if "%%A" neq "%#mapCodePage%" call charMacros

:: Test the Str2Hex macro
setlocal
set "str=Hello world!"
%@Str2Hex% str hex
echo str=%str%
echo hex=%hex%

-- OUTPUT --

str=Hello world!
hex=48656C6C6F20776F726C6421
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top