<http://www.netikka.net/tsneti/info/tscmd088.htm>
Copyright © 2003- by Prof. Timo Salmi  
Last modified Fri 2-Jan-2015 17:15:10

 
Assorted NT/2000/XP/.. CMD.EXE Script Tricks
From the html version of the tscmd.zip 1cmdfaq.txt file
To the Description and the Index
 

This page is edited from the 1cmdfaq.txt faq-file contained in my tscmd.zip command line interface (CLI) collection. That zipped file has much additional material, including a number of detached .cmd script files. It is recommended that you also get the zipped version as a companion.

Please see "The Description and the Index page" for the conditions of usage and other such information.



88} How to convert DEC to HEX with a script file, and vice versa? (revisited)

If you want a pure script only solution, see items 32 and 33 in this FAQ. If you want to convert a string given in hexadecimals see item 73. For a command-line calculator type of a solution for Dec to Hex (etc) see item 61.

This can be also done e.g. with G(nu)AWK or a Visual Basic Script (VBScript). The gawk solutions are given below. No error checking for the correct input format of the digits is included in the conversion algorithms. To put the results in an environment variable see the DEC to BIN awk and VBScript examples in this item.

  @echo off & setlocal enableextensions disabledelayedexpansion
  rem DEC to HEX
  ::
  :: Usage

  if "%~1"=="" (
    echo.
    echo Usage: %~f0 [DecimalNumber] to be converted to Hexadecimal
    goto :EOF)
  ::
  :: Build an awk source

  set awksrc="%temp%\tmp$$$.awk"
  >  %awksrc% echo BEGIN{
  >> %awksrc% echo number=%1
  >> %awksrc% echo base=16
  >> %awksrc% echo digit="0123456789ABCDEF"
  >> %awksrc% echo result=""
  >> %awksrc% echo while(number!=0)
  >> %awksrc% echo   {
  >> %awksrc% echo     i=number-base*int(number/base)
  >> %awksrc% echo     result=substr(digit,i+1,1)result
  >> %awksrc% echo     number=int(number/base)
  >> %awksrc% echo   }
  >> %awksrc% echo printf"%%s\n",result
  >> %awksrc% echo }
  ::
  :: Run the awk source

  gawk -f %awksrc%
  ::
  :: Clean up

  for %%f in (%awksrc%) do if exist %%f del %%f
  endlocal & goto :EOF

An example of the output
  C:\_D\TEST>cmdfaq 127
  7F
As is seen the above can be easily generalized by changing the "base" variable. The same goes for the other cases.

In the special case of DEC to HEX gawk inbuilt features can alternatively be used as a simple shortcut:
  @echo off & setlocal enableextensions
  rem DEC to HEX
  ::
  if "%~1"=="" (
    echo.
    echo Usage: %~f0 [DecimalNumber] to be converted to Hexadecimal
    goto :EOF)
  ::
  gawk 'BEGIN{printf"%%X\n","%~1"}'
  ::
  endlocal & goto :EOF

The other way round the HEX to DEC code is
  @echo off & setlocal enableextensions disabledelayedexpansion
  rem HEX to DEC
  ::
  :: Usage

  if "%~1"=="" (
    echo.
    echo Usage: %~f0 [HexNumber] to be converted to Decimal
    goto :EOF)
  ::
  :: Build an awk source

  set awksrc="%temp%\tmp$$$.awk"
  >  %awksrc% echo BEGIN{
  >> %awksrc% echo k=1
  >> %awksrc% echo d=0
  >> %awksrc% echo base=16
  >> %awksrc% echo number=toupper("%1")
  >> %awksrc% echo i=length(number)+1
  >> %awksrc% echo while(i!=1)
  >> %awksrc% echo   {
  >> %awksrc% echo    i--
  >> %awksrc% echo    j=index("123456789ABCDEF",substr(number,i,1))
  >> %awksrc% echo    d=d+j*k
  >> %awksrc% echo    k=base*k
  >> %awksrc% echo   }
  >> %awksrc% echo printf"%%s in HEX is %%s in DEC\n",number,d
  >> %awksrc% echo }
  ::
  :: Run the awk source

  gawk -f %awksrc%
  ::
  :: Clean up

  for %%f in (%awksrc%) do if exist %%f del %%f
  endlocal & goto :EOF

An example of the output
  C:\_D\TEST>cmdfaq FD
  FD in HEX is 253 in DEC

Let's consider the conversion from decimal to binary and putting the result into an environment variable.
  @echo off & setlocal enableextensions
  rem DEC to BIN
  ::
  :: Usage

  if "%~1"=="" (
    echo.
    echo Usage: %~f0 [DecimalNumber] to be converted to Binary
    goto :EOF)
  ::
  :: Build an awk source

  set awksrc="%temp%\tmp$$$.awk"
  >  %awksrc% echo BEGIN{
  >> %awksrc% echo number=%1
  >> %awksrc% echo base=2
  >> %awksrc% echo digit="0123456789ABCDEF"
  >> %awksrc% echo result=""
  >> %awksrc% echo while(number!=0)
  >> %awksrc% echo   {
  >> %awksrc% echo    i=number-base*int(number/base)
  >> %awksrc% echo    result=substr(digit,i+1,1)result
  >> %awksrc% echo    number=int(number/base)
  >> %awksrc% echo   }
  >> %awksrc% echo printf"@set bin_=%%s\n",result
  >> %awksrc% echo }
  ::
  :: Run the awk source and the created command script

  set myscript="%temp%\tmp$$$.cmd"
  gawk -f %awksrc%>%myscript%
  call %myscript%
  ::
  :: Clean up

  for %%f in (%awksrc% %myscript%) do if exist %%f del %%f
  ::
  :: Display the results

  echo %1 DEC = %bin_% BIN
  endlocal & goto :EOF

An example of the output
  C:\_D\TEST>cmdfaq 12
  12 DEC = 1100 BIN

A VBScript-aided solution for the Decimal to Binary conversion is given below
  @echo off & setlocal enableextensions
  rem DEC to BIN
  ::
  :: Usage

  if "%~1"=="" (
    echo.
    echo Usage: %~f0 [DecimalNumber] to be converted to Binary
    goto :EOF)
  ::
  :: Build a Visual Basic Script and run it with Microsoft Windows Script Host

  findstr "'%skip%VBS" "%~f0" > "%temp%\tmp$$$.vbs"
  cscript //nologo "%temp%\tmp$$$.vbs" %1 > "%temp%\tmp$$$.cmd"
  ::
  :: Utilize the output and display the result

  call "%temp%\tmp$$$.cmd"
  echo Decimal %1 in Binary = %bin_%
  ::
  :: Clean up

  for %%f in ("%temp%\tmp$$$.vbs" "%temp%\tmp$$$.cmd") do if exist %%f del %%f
  endlocal & goto :EOF
  '
  number=WScript.Arguments.Unnamed(0) 'VBS
  base=2 'VBS
  digit="0123456789ABCDEF" 'VBS
  result="" 'VBS
  While number <> 0 'VBS
    i = number - base * Int(number/base) 'VBS
    result = Mid(digit,i+1,1) & result 'VBS
    number = Int(number/base) 'VBS
  Wend 'VBS
  WScript.Echo "@set bin_=" & result 'VBS

An example of the output
  C:\_D\TEST>cmdfaq 12
  Decimal 12 in Binary = 1100

Since VBScript has a Hex function, for the Decimal to Hexadecimal the while loop and the three lines above it can simply be replaced with
  result = Hex(number) 'VBS
The same goes for octal.

To conclude the item one more VBScript-aided solution version:
  @echo off & setlocal enableextensions
  rem HEX to DEC
  ::
  :: Usage

  if "%~1"=="" (
    echo.
    echo Usage: %~f0 [HexNumber] to be converted to Decimal
    goto :EOF)
  ::
  :: Build a Visual Basic Script and run it with Microsoft Windows Script Host

  findstr "'%skip%VBS" "%~f0" > "%temp%\tmp$$$.vbs"
  cscript //nologo "%temp%\tmp$$$.vbs" %1 > "%temp%\tmp$$$.cmd"
  ::
  :: Utilize the output and display the result

  call "%temp%\tmp$$$.cmd"
  echo Hexadecimal %1 in Decimal = %dec_%
  ::
  :: Clean up

  for %%f in ("%temp%\tmp$$$.vbs" "%temp%\tmp$$$.cmd") do if exist %%f del %%f
  endlocal & goto :EOF
  '
  number=WScript.Arguments.Unnamed(0) 'VBS
  k = 1 'VBS
  d = 0 'VBS
  base = 16 'VBS
  number=UCase(number) 'VBS
  i = Len(number) + 1 'VBS
  While i > 1 'VBS
    i = i - 1 'VBS
    j = Instr (1, "123456789ABCDEF", Mid(number,i,1), 0) 'VBS
    d = d + (j * k) 'VBS
    k = base * k 'VBS
  Wend 'VBS
  WScript.Echo "@set dec_=" & d 'VBS

An example of the output
  C:\_D\TEST>cmdfaq 1a
  Hexadecimal 1a in Decimal = 26
Written slightly differently
  @echo off & setlocal enableextensions
  rem HEX to DEC
  ::
  :: Usage

  if "%~1"=="" (
    echo.
    echo Usage: %~f0 [HexNumber] to be converted to Decimal
    goto :EOF)
  ::
  :: Build a Visual Basic Script
  :: and run it with Microsoft Windows Script Host

  set skip=
  findstr "'%skip%VBS" "%~f0" > "%temp%\tmp$$$.vbs"
  for /f "tokens=* delims=" %%a in (
    'cscript //nologo "%temp%\tmp$$$.vbs" %1') do set dec_=%%a
  ::
  :: Utilize the output and display the result

  echo Hexadecimal %1 in Decimal = %dec_%
  ::
  :: Clean up

  for %%f in ("%temp%\tmp$$$.vbs") do if exist %%f del %%f
  endlocal & goto :EOF
  '
  number=WScript.Arguments.Unnamed(0) 'VBS
  k = 1 'VBS
  d = 0 'VBS
  base = 16 'VBS
  number=UCase(number) 'VBS
  i = Len(number) + 1 'VBS
  While i > 1 'VBS
    i = i - 1 'VBS
    j = Instr (1, "123456789ABCDEF", Mid(number,i,1), 0) 'VBS
    d = d + (j * k) 'VBS
    k = base * k 'VBS
  Wend 'VBS
  WScript.Echo d 'VBS

Let's draw all this together for a real-life situation. I need a single script that converts between the following bases: binary, octal, decimal and hexadecimal. This is what I use. (Why the name BASE7.CMD? Because on XP I have a 16-bit program BASE.EXE for the same purpose. The current script is for my 64-bit Windows 7 PC.)
  @echo off & setlocal enableextensions
  rem enabledelayedexpansion
  rem C:\_F\XTOOLS\BASE7.CMD
  rem FromBase ToBase Number
  ::

  call :programTitle
  set help_=
  if "%~3"==""   set help_=true
  if "%~1"=="?"  set help_=true
  if "%~1"=="/?" set help_=true
  if defined help_ (
    call :ProgramHelp
    goto _out)
  ::
  :: Assign a value for the temporary folder variable temp_

  call :AssignTemp temp_
  ::
  :: The awk program, customize as is relevant for you
  :: No spaces allowed in the file path

  set awkprog_=C:\_F\FTOOLS\unxgawk.exe
  call :CheckExistence Program "%awkprog_%" found_
  if not defined found_ goto _out
  ::
  call :CheckParam "%~1" "%~2" "%~3" invalid_
  if defined invalid_ (
    echo/
    call :ProgramHelp
    goto _out)
  ::
  call :BaseToDec "%~3" "%~1" dec_
  echo %~3 in base %~1 is %dec_% in decimal (base 10)
  call :DecToBase "%dec_%" "%~2" x_
  echo %dec_% in base 10 (decimal) is %x_% in base %~2
  echo Thus %~3 in base %~1 is %x_% in base %~2
  ::
  :_out
  if not defined cmdbox if defined PauseIfFromDesktop pause
  endlocal & goto :EOF
 
  :ProgramTitle
  echo/
  echo +-----------------------------------------------------+
  echo BASE7.CMD Convert numbers between different bases   
  echo By Prof. Timo Salmi, Last modified Fri 2-Jan-2015   
  echo +-----------------------------------------------------+
  echo/
  goto :EOF
 
  :ProgramHelp
  echo Usage: BASE7 FromBase ToBase Number
  echo/
  echo Works best for bases 2, 8, 10, and 16
  goto :EOF
 
  :AssignTemp
  setlocal
  set return_=%temp%
  if defined mytemp if exist "%mytemp%\" set return_=%mytemp%
  endlocal & set "%1=%return_%" & goto :EOF
 
  :DecToBase
  setlocal enableextensions disabledelayedexpansion
  set awksrc=%temp_%\tmp$$$.awk
  >  "%awksrc%" echo BEGIN{
  >> "%awksrc%" echo number=%~1
  >> "%awksrc%" echo base=%~2
  >> "%awksrc%" echo digit="0123456789ABCDEF"
  >> "%awksrc%" echo result=""
  >> "%awksrc%" echo while(number!=0)
  >> "%awksrc%" echo   {
  >> "%awksrc%" echo     i=number-base*int(number/base)
  >> "%awksrc%" echo     result=substr(digit,i+1,1)result
  >> "%awksrc%" echo     number=int(number/base)
  >> "%awksrc%" echo   }
  >> "%awksrc%" echo printf"%%s\n",result
  >> "%awksrc%" echo }
  ::
  :: Run the awk source

  for /f "usebackq" %%a in (`%awkprog_% -f "%awksrc%"`) do set return_=%%a
  ::
  :: Clean up

  for %%f in ("%awksrc%") do if exist %%f del %%f
  endlocal & set "%3=%return_%" & goto :EOF
 
  :BaseToDec
  setlocal enableextensions disabledelayedexpansion
  set awksrc=%temp_%\tmp$$$.awk
  >  "%awksrc%" echo BEGIN{
  >> "%awksrc%" echo k=1
  >> "%awksrc%" echo d=0
  >> "%awksrc%" echo base=%~2
  >> "%awksrc%" echo number=toupper("%~1")
  >> "%awksrc%" echo i=length(number)+1
  >> "%awksrc%" echo while(i!=1)
  >> "%awksrc%" echo   {
  >> "%awksrc%" echo     i--
  >> "%awksrc%" echo     j=index("123456789ABCDEF",substr(number,i,1))
  >> "%awksrc%" echo     d=d+j*k
  >> "%awksrc%" echo     k=base*k
  >> "%awksrc%" echo   }
  >> "%awksrc%" echo printf"%%s\n",d
  >> "%awksrc%" echo }
  ::
  :: Run the awk source

  for /f "usebackq" %%a in (`%awkprog_% -f "%awksrc%"`) do set return_=%%a
  ::
  :: Clean up

  for %%f in ("%awksrc%") do if exist %%f del %%f
  endlocal & set "%3=%return_%" & goto :EOF
 
  :: Perform some input parameter validity checking, not airtight
  :CheckParam
  setlocal enableextensions
  set invalid_=
  ::
  echo %~1|findstr /r "[^0-9]">nul
  if %errorlevel% EQU 0 (
    set invalid_=true
    echo FromBase %~1 contains invalid characters
    goto _eofCheckParam)
  ::
  echo %~2|findstr /r "[^0-9]">nul
  if %errorlevel% EQU 0 (
    echo ToBase %~2 contains invalid characters
    set invalid_=true
    goto _eofCheckParam)
  ::
  echo %~3|findstr /r "[^0-9^a-f^A-F]">nul
  if %errorlevel% EQU 0 (
    echo The number to be converted %~3 contains invalid characters
    set invalid_=true
    goto _eofCheckParam)
  ::
  if %~1 LEQ 1 (
    set invalid_=true
    echo The value %~1 of FromBase is less than 2
    goto _eofCheckParam)
  if %~2 LEQ 1 (
    set invalid_=true
    echo Thealue %~2 of ToBase is less than 2
    goto _eofCheckParam)
  ::
  if %~1 GTR 16 (
    set invalid_=true
    echo The value %~1 of FromBase is greater than 16
    goto _eofCheckParam)
  if %~2 GTR 16 (
    set invalid_=true
    echo The value %~2 of ToBase is greater than 16
    goto _eofCheckParam)
  if %~3 LSS 0 (
    set invalid_=true
    echo The value %~3 is negative
    goto _eofCheckParam)
  ::
  echo %~3|findstr /r "[^0-9]">nul
  if %errorlevel% EQU 0 if "%~1"=="10" (
    set invalid_=true
    echo The value to be convereted %~3 contains chracters outside the decimal base
    goto _eofCheckParam)
  ::
  echo %~3|findstr /r "[^0-7]">nul
  if %errorlevel% EQU 0 if "%~1"=="8" (
  set invalid_=true
  echo The value to be convereted %~3 contains chracters outside the octal base
  goto _eofCheckParam)
  ::
  echo %~3|findstr /r "[^0-1]">nul
  if %errorlevel% EQU 0 if "%~1"=="2" (
    set invalid_=true
    echo The value to be convereted %~3 contains chracters outside the binary base
    goto _eofCheckParam)
  ::
  :_eofCheckParam
  endlocal & set "%4=%invalid_%" & goto :EOF
 
  :CheckExistence
  setlocal enableextensions
  set file_=%2
  if exist %file_% (endlocal & set "%3=true" & goto :EOF)
  echo %~1 %file_% not found
  endlocal & set "%3=" & goto :EOF
 
  :: For debugging, show verbally the value of an environment variable
  :ShowVarValue TheNameOfTheVariable
  setlocal
  set par1_=%~1
  call set value_=%%%par1_%%%
  echo The value of %~1 is %value_%
  endlocal & goto :EOF

The output might be e.g.
 
  C:\_D\TEST>base7 16 8 FE
 
  +-----------------------------------------------------+
  BASE8.CMD Convert numbers between different bases  
  By Prof. Timo Salmi, Last modified Fri 2-Jan-2015  
  +-----------------------------------------------------+
 
  FE in base 16 is 254 in decimal (base 10)
  254 in base 10 (decimal) is 376 in base 8
  Thus FE in base 16 is 376 in base 8

References/Comments: (If a Google message link fails try the links within the brackets.)
  Google Groups Apr 27 2010, 8:12 pm [M]
  Number converter - hex, octal, binary | Coder’s Toolbox