1 (изменено: torus, 2016-05-20 13:41:25)

Тема: CMD/BAT: Преобразование системы счисления

Код :

@echo off
setlocal enabledelayedexpansion
if /i "%1"=="-d2h" Call :dec2hex %2 result
if /i "%1"=="-h2d" Call :hex2dec %2 result
if "%3"=="" (echo !result!&endlocal&goto :eof) else (endlocal&set %3=%result%)
exit /b

:hex2dec
setlocal
set txt=%1
Call :strlen len %1
set min=0
set /a "max=0"
set /a "bstr=len - 1"
set long[0]=0
for /l %%i in (0,1,!bstr!) do (
	for /l %%a in (!min!,1,!max!) do set /a long[%%a]*=16
	Call :verifyDecVal
	set /a long[!min!]+=0x!txt:~%%i,1!
)
Call :verifyDecVal
set q=
for /l %%i in (!max!,-1,!min!) do (
	set t=0000!long[%%i]!
	set q=!q!!t:~-4!
)
endlocal&set result=%q%
goto :eof

:verifyDecVal
set again=false
for /l %%a in (!min!,1,!max!) do (
	if "%%a"=="!max!" (
		if !long[%%a]! geq 10000 (
			set again=true
			set /a max+=1
			set /a "long[!max!]=long[%%a] / 10000"
			set /a "long[%%a]=long[%%a] %% 10000"
		)
	)
)
set /a "mmax=max - 1"
for /l %%i in (!min!,1,!mmax!) do (
	set /a next=%%i + 1
	if !long[%%i]! geq 10000 (
		set again=true
		set /a "long[!next!]+=long[%%i] / 10000"
		set /a "long[%%i]=long[%%i] %% 10000"
	)
)
if !again!==true goto verifyDecVal
goto :eof

:dec2hex
setlocal
set txt=%1
Call :strlen len %1
set min=0
set /a "max=0"
set /a "bstr=len - 1"
set long[0]=0
for /l %%i in (0,1,!bstr!) do (
	for /l %%a in (!min!,1,!max!) do set /a long[%%a]*=10
	Call :verifyHexVal
	set /a long[!min!]+=!txt:~%%i,1!
)
Call :verifyHexVal
set result=
for /l %%i in (!max!,-1,!min!) do (
	Call :toHex !long[%%i]! q
	set result=!result!!q:~-4!
)
endlocal&set result=%result%
goto :eof

:verifyHexVal
set again=false
for /l %%a in (!min!,1,!max!) do (
	if "%%a"=="!max!" (
		if !long[%%a]! geq 65536 (
			set again=true
			set /a max+=1
			set /a "long[!max!]=long[%%a] >> 16"
			set /a "long[%%a]=long[%%a] & 0xFFFF"
		)
	)
)
set /a "mmax=max - 1"
for /l %%i in (!min!,1,!mmax!) do (
	set /a next=%%i + 1
	if !long[%%i]! geq 65536 (
		set again=true
		set /a "long[!next!]+=long[%%i] >> 16"
		set /a "long[%%i]=long[%%i] & 0xFFFF"
	)
)
if !again!==true goto verifyHexVal
goto :eof

:strlen <resultVar> <stringVar>
(   
    setlocal EnableDelayedExpansion
    set "s=%~2#"
    set "len=0"
    for %%P in (4096 2048 1024 512 256 128 64 32 16 8 4 2 1) do (
        if "!s:~%%P,1!" NEQ "" ( 
            set /a "len+=%%P"
            set "s=!s:~%%P!"
        )
    )
)
( 
    endlocal
    set "%~1=%len%"
    exit /b
)

:toHex dec hex -- convert a decimal number to hexadecimal, i.e. -20 to FFFFFFEC or 26 to 0000001A
::             -- dec [in]      - decimal number to convert
::             -- hex [out,opt] - variable to store the converted hexadecimal number in
::Thanks to 'dbenham' dostips forum users who inspired to improve this function
:$created 20091203 :$changed 20110330 :$categories Arithmetic,Encoding
:$source http://www.dostips.com
SETLOCAL ENABLEDELAYEDEXPANSION
set /a dec=%~1
set "hex="
set "map=0123456789ABCDEF"
for /L %%N in (1,1,8) do (
    set /a "d=dec&15,dec>>=4"
    for %%D in (!d!) do set "hex=!map:~%%D,1!!hex!"
)
rem !!!! REMOVE LEADING ZEROS by activating the next line, e.g. will return 1A instead of 0000001A
rem for /f "tokens=* delims=0" %%A in ("%hex%") do set "hex=%%A"&if not defined hex set "hex=0"
( ENDLOCAL & REM RETURN VALUES
    IF "%~2" NEQ "" (SET %~2=%hex%) ELSE ECHO.%hex%
)
EXIT /b

toHex из http://www.dostips.com/DtCodeCmdLib.php#Function.toHex