从 Windows Batch 中的 ASCII 代码返回字符

问题描述 投票:0回答:3

我编写了一个用于批量编码文本字符串的程序。现在,我必须将 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
)

该命令似乎不起作用。我该如何解决这个问题?

windows batch-file cmd char ascii
3个回答
3
投票
@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
无法自行处理)。


1
投票

这里是老板。就读、放屁、鼓掌。

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

1
投票

当我使用

!=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
© www.soinside.com 2019 - 2024. All rights reserved.