我编写了一个用于批量编码文本字符串的程序。现在,我必须将 ASCII 代码转换为字符。事实上,我必须做相反的事情。 我划分了字符串的字符,我想将其转换为 ASCII。 我发现了一个将 ASCII 转换为 char 的好命令:
cmd /c exit 65
echo %=exitcodeAscii%
但是,当我在 for 循环中运行它时,它停止工作。通过 for 迭代,我验证 ASCII 代码(for 索引)是否与字符相同。
@echo off
setlocal enableDelayedExpansion
set char=A
for /L %%a in (32,1,126) do (
cmd /c exit %%a
echo %=exitcodeAscii%
if %=exitcodeAscii% EQU %char% echo %%a
)
该命令似乎不起作用。我该如何解决这个问题?
@echo off
setlocal enableDelayedExpansion
set char=A
for /L %%a in (32,1,126) do (
cmd /c exit %%a
echo !=exitcodeAscii!
if "!=exitcodeAscii!" EQU "%char%" echo %%a
)
两个小变化:
a) 使用延迟扩展(您已经启用它)
b) 围绕
if
参数进行引用,以防止空变量出现语法错误(特别是这里 %%a = 32
的空间,if
无法自行处理)。
这里是老板。就读、放屁、鼓掌。
cls
@echo off
cd /d "%~dp0"
chcp 65001 >nul
set title_script=char to hex
title %title_script%
rem Encode this file script in UTF-8 with BOM and let the first line blank
set ansi_code_page=1252
rem 1250 Central European
rem 1251 Cyrillic
rem 1252 Western European (Latin 1)
rem 1253 Greek
rem 1254 Turkish
rem 1255 Hebrew
rem 1256 Arabic
rem 1257 Baltic
rem 1258 Vietnamese
chcp %ansi_code_page% >nul
set /p character=Character =
set "character_ascii="
call :function_char_to_ascii character character_ascii
echo Character %character% = %character_ascii%
pause
exit
:function_char_to_hex
setlocal enabledelayedexpansion
set character=!%~1!
set tmp_file=%~dpn0_tmp.txt
echo !character!> "%tmp_file%"
set tmp_0_file=%~dpn0_tmp_0.txt
for %%a in ("%tmp_file%") do fsutil file createnew "%tmp_0_file%" %%~za >nul
set "character_hex="
for /f "skip=1 tokens=2" %%a in ('fc /B "%tmp_file%" "%tmp_0_file%"') do set "character_hex=!character_hex!%%a"
del /f /q "%tmp_file%"
del /f /q "%tmp_0_file%"
if /i "%character_hex:~-4%" == "0D0A" set character_hex=%character_hex:~0,-4%
endlocal & set %~2=%character_hex%
goto :eof
:function_change_base_number
setlocal enabledelayedexpansion
set /a input_base=%~1
set input_number=!%~2!
set /a output_base=%~3
for %%i in ("a=A" "b=B" "c=C" "d=D" "e=E" "f=F" "g=G" "h=H" "i=I" "j=J" "k=K" "l=L" "m=M" "n=N" "o=O" "p=P" "q=Q" "r=R" "s=S" "t=T" "u=U" "v=V" "w=W" "x=X" "y=Y" "z=Z") do (
call set "input_number=!input_number:%%~i!"
)
set map=0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ
set map_base=!map:~0,%input_base%!
set /a position=0
set input_number_check=%input_number%
:loop_1
set current_map_base_character=!map_base:~%position%,1!
set input_number_check=!input_number_check:%current_map_base_character%=!
if "!input_number_check!" == "" goto next_1
set /a position+=1
if "!map_base:~%position%,1!" NEQ "" goto loop_1
echo Error. Invalid character in base %input_base%.
echo.
pause
exit
:next_1
set /a carry_flag=1
set "input_number_tmp=%input_number%"
set "result_decimal="
:loop_2
set "input_number_tmp_digit=%input_number_tmp:~-1%"
if %input_number_tmp_digit% LEQ 9 goto next_2
for /l %%i in (10,1,%input_base%) do (
if /i "%input_number_tmp_digit%" EQU "!map:~%%i,1!" (
set "input_number_tmp_digit=%%i"
goto :next_2
)
)
echo Error.
:next_2
set /a result_decimal+=input_number_tmp_digit * carry_flag
set /a carry_flag *= input_base
set "input_number_tmp=%input_number_tmp:~0,-1%"
if defined input_number_tmp goto :loop_2
set /a input_number_tmp=%result_decimal%
set "result="
:loop_3
set /a "division_remainder=input_number_tmp %% !output_base!"
set /a "input_number_tmp /= !output_base!"
set result=!map:~%division_remainder%,1!%result%
if "%input_number_tmp%" NEQ "0" goto loop_3
endlocal & set %~4=%result%
goto :eof
:function_char_to_ascii
setlocal enabledelayedexpansion
set "character=!%~1!"
set "character_hex="
set "character_dec="
rem Character " is forbidden
if "%character%" == " " (
set "character_hex=20"
set "character_dec=32"
)
rem On this line, write a tabulation between the quotes, not 4 spaces.
if "%character%" == " " (
set "character_hex=9"
set "character_dec=9"
)
if "%character%" == ")" (
set "character_hex=29"
set "character_dec=41"
)
if "%character_hex%" == "" (
set "character_hex="
call :function_char_to_hex character character_hex
set "character_dec="
call :function_change_base_number 16 character_hex 10 character_dec
)
rem echo %character% = %character_dec% (x%character_hex%)
endlocal & set %~2=%character_dec%
goto :eof
当我使用
!=exitcodeAscii!
进行多个字符匹配时,它会执行得很慢,我不知道为什么。
set "ascii_str= #$%%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~"
echo %time%
:ascii_multiple
if defined ascii_str (
set "char=!ascii_str:~0,1!"
for /l %%0 in (32, 1, 126) do cmd /c exit %%0 &if "!=exitcodeAscii!" EQU "!char!" echo %%0
set "ascii_str=!ascii_str:~1!"
) else (echo %time% &pause)
goto ascii_multiple
开始:11:21:27.00 结束:11:22:29.25 约1分钟
但是,如果我采用一种新方法将字符或字符串转换为 Ascii:
@echo off &setlocal EnableDelayedExpansion
chcp 1252 >nul
set "ascii_table= #$%%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~"
set "ascii[33]=^!" &set "ascii[34]=""
:main
set /p "string=String:"
call :str_ascii
echo. &goto main
:str_ascii
if defined string (
set "char=!string:~0,1!"
call :char_ascii
set "string=!string:~1!"
) else (exit /b 0)
goto str_ascii
:char_ascii
set /a index=32
if "!char!"=="!ascii[33]!" echo !ascii[33]! = 33 &exit /b 0
if "!char!"=="!ascii[34]!" echo !ascii[34]! = 34 &exit /b 0
if "!char!"=="" exit /b 1
for /l %%0 in (0, 1, 94) do (
if "!char!"=="!ascii_table:~%%0,1!" echo !char! = !index! &exit /b 0
set /a index+=1)
echo cannot find char &exit /b 1
在这个函数中,我可以处理Ascii char 32-126。
在这种情况下我尝试使用查表来提高效率。
我认为
!=exitcodeAscii!
需要执行太多命令,因为如果你想找到最后一个字符~
你可能需要执行命令94次。
因此,我将所有 Ascii 字符放入一个字符串中,并使用
!ascii_table:~%%0,1!
获取 ascii 表中的单个字符,并设置 /a 索引来计算 Decimal 值。
就像逐一设置数组并相互匹配字符一样:
set "ascii[32]= "
...
set "ascii[126]=~"
测试字符串:
!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~
所有角色的运行速度为 19:33:32.19 至 19:33:32.94 - 不到 1 秒。
如果您想使用十进制值来查找字符,您还可以更改一些代码:
:main
set /p "enter=Decimal:"
if defined enter set /a dec=%enter% &call :dec_ascii
echo. &goto main
:dec_ascii
set /a index=32
if !dec!==33 echo !ascii[33]! &exit /b 0
if !dec!==34 echo !ascii[34]! &exit /b 0
if not defined dec exit /b 1
for /l %%0 in (0, 1, 94) do (
if !dec!==!index! echo !ascii_table:~%%0,1! &exit /b 0
set /a index+=1)
echo cannot find char &exit /b 1