返回列表 发帖

[文本处理] 求助批处理字符串(UTF-8)转换成十六进制(HEX), 找到一个vbs可以转换

以下代码是我找到的一个 ascii 到 hex 的批处理, 但无法处理中文字符串.
set strLN=
set str=string
>str set /p=%str%<nul
for /f "tokens=3,*" %%i in ('dir str ^| findstr 个文件') do (
set /a "nLen=%%i"
)
set "strCmp="
for /l %%i in (1 1 %nLen%) do (
call set "strCmp=%%strCmp%%%%strLN%%"
)
>$ set /p=%strCmp%<nul
set "strASC="
for /f "skip=1 tokens=2 delims=: " %%i in ('fc /b str $') do (
call set "strASC=%%strASC%%%%i "
)
echo %strASC%
pauseCOPY
或者是调用第三方程序处理后再设置为变量的方法也可以.

找到一个vbs, 可以将中文转换成hex
str="中文"
Set ado=CreateObject("ADODB.Stream")
Set xmldom=CreateObject("msxml2.domdocument")
ado.Type=2
ado.Charset="GB2312"
ado.Open
ado.WriteText str
ado.Position=0
ado.Type=1
Set pic=xmldom.createElement("pic")
pic.dataType="bin.hex"
pic.nodeTypedValue=ado.Read(-1)
WScript.Echo UCase(pic.text)
ado.CloseCOPY
能不能用批处理设置一个变量让该vbs读取后再输出为批处理中的变量

TOP

本帖最后由 523066680 于 2025-3-10 11:18 编辑

倒是写过一个剪切板工具,把剪切板里的字符(或者调用时传参),默认按gbk解读(脚本里也可以改其他编码),然后"翻译"成各种编码的16进制后打印出来
decode.pl
C:\Users\Default>decode.pl 中文
d6 d0 ce c4     gbk
a4 a4 a4 e5     big5
e4 b8 ad e6 96 87       utf8
2d 4e 87 65     utf16-le
4e 2d 65 87     utf16-be
20013 25991     Unicode
4E2D 6587       Unicode
\xE4\xB8\xAD\xE6\x96\x87        utf8COPY
Perl这个东西太冷门了,所以……  当我没说。
1

评分人数

    • zzz19760225: 如果象sed.exe那样的独立perl.exe,会不会好 ...技术 + 1
[url=][/url]

TOP

回复 1# akari

fc.exe 加持参数 /u,用以下代码试试...
@echo off &setlocal &set "sc=中文字符串"
set/p="%sc%"<nul>$.0&for %%l in ($.0) do (fsutil file createnew "$.1" %%~zl)>nul 2>nul
for /f "skip=1 tokens=2 delims=: " %%a in ('fc /b /u $.0 $.1') do (call set "sx=%%sx%%%%a ")
del/q "$.?" &echo,%sx%
pause&exit/bCOPY

TOP

本帖最后由 akari 于 2025-3-10 12:25 编辑

回复 4# aloha20200628


    感谢你的帮助, 但我还有一些疑惑.
    中文字符串 转换成16进制完整的应该是 D6 D0 CE C4 D7 D6 B7 FB B4 AE
    但是你这个批处理为什么只显示了绿色的部分?

    看了一下fc.exe的参数说明,又搜索了一下,UNICODE字符集,是这个问题吧

TOP

总算是找到解决办法了. 调用powershell可以实现, 以下是
@echo off
setlocal enabledelayedexpansion
set "text=中文"
for /f "delims=" %%a in (
    'powershell -ExecutionPolicy Bypass -Command "$bytes=[System.Text.Encoding]::UTF8.GetBytes('%text%'); $hexStr=[System.BitConverter]::ToString($bytes); $hexStr.Replace('-', ' ')"'
) do (
    set "hex=%%a"
)
echo HEX: !hex!
endlocal
pauseCOPY

TOP

下载coder.exe
coder -r 16 ec -s 中文COPY
coder -c ansi utf-8 -s 中文|coder -r 16 ec -sCOPY

TOP

本帖最后由 aloha20200628 于 2025-3-10 13:55 编辑

回复 5# akari

若4楼代码被存为 utf-8 编码文件运行,须用以下代码
@echo off &chcp 65001>nul
setlocal &set "sc=中文字符串"
set/p="%sc%"<nul>$.1&for %%l in ($.1) do (fsutil file createnew "$.0" %%~zl)>nul 2>nul
for /f "skip=1 tokens=2 delims=: " %%a in ('fc /b /u $.1 $.0') do (call set "sx=%%sx%%%%a ")
del/q "$.?" &echo,%sx%
pause&exit/bCOPY
如果以上代码被存为 gb2312 编码(即记事本的ANSI编码)文件运行,则须修改其中第一行的 65001 为 936 即可...
1

评分人数

    • akari: 这个可以, 稍加改动我就可以使用了,非常感谢 ...技术 + 1

TOP

本帖最后由 akari 于 2025-3-10 16:44 编辑

回复 8# aloha20200628


    转换出来依旧不是 UTF-8 HEX, "中文" 转换 UTF-8 HEX 为 E4 B8 AD E6 96 87, 而不是 D6 D0 CE C4.
    能改改转换成UTF-8 HEX 么?
@echo off
chcp 65001 >nul
setlocal enabledelayedexpansion
set "str=中文"
call :text2hex
exit /b
:text2hex
rem 将 str 的值赋给 sc
set "sc=!str!"
rem 使用 `set /p` 避免换行符
<nul set /p=!sc! >$.1
rem 计算文件大小
for %%l in ($.1) do fsutil file createnew "$.0" %%~zl >nul 2>nul
set "sx="
rem 以二进制方式读取并转换为 HEX
for /f "skip=1 tokens=2 delims=: " %%a in ('fc /b $.1 $.0') do (
    call set "sx=%%sx%% %%a"
)
del /q "$.?" >nul 2>nul
echo HEX: %sx%
pauseCOPY
改成这样ok了.

TOP

回复 9# akari

中文数据的utf-8编码与其ANSI编码是不同的,与之对应的16进制码数自然也是不同的...
8楼代码中的sc变量替换为 中文,用65001版获取的16进制码数应为 E4 B8 AD E6 96 87,而用936版获取的应为 D6 D0 CE C4。

TOP

回复 10# aloha20200628


    没办法最终还是改成这个了
powershell -Command "[System.IO.File]::WriteAllBytes('$.1', [System.Text.Encoding]::UTF8.GetBytes('%str%'))"COPY

TOP

ansi环境下 ,中文二字直接换成bat变量就行

node.js
https://nodejs.org/download/release/v4.9.1/win-x86/
下exe ,添加到环境变量即可
node -e "console.log(new Buffer('中文'))"COPY
python
https://www.python.org/downloads/windows/
版本3.5以上 ,下embeddable版 ,解压后添加环境变量即可
python -c "print('中文'.encode().hex())"COPY
ruby
https://rubyinstaller.org/downloads/
下zip版 ,解压后添加环境变量即可
ruby -e "puts '中文'.encode('utf-8').unpack('H*')"COPY
bat ,编码保存为ansi ,输出干扰较多
@echo off&chcp 936>nul
set "str=中文"
chcp 65001>nul
setlocal enabledelayedexpansion
echo,!str! >"!TEMP!\$$"
endlocal&chcp 936>nul
certutil -dump "%TEMP%\$$"
pause&exit/bCOPY

TOP

本帖最后由 aloha20200628 于 2025-3-10 18:47 编辑

回复 11# akari

用以下这个版本就可以了,代码存为 ANSI(gb2312)编码运行,最后获取的变量 sx 值就是 E4 B8 AD E6 96 87 ...
@echo off &chcp 936>nul
del/q "$.?" 2>nul &setlocal &set "sc=中文" &chcp 65001>nul
set/p="%sc%"<nul>$.1&for %%l in ($.1) do (fsutil file createnew "$.0" %%~zl)>nul 2>nul
for /f "skip=1 tokens=2 delims=: " %%a in ('fc /b /u $.1 $.0') do (call set "sx=%%sx%%%%a ")
chcp 936>nul &del/q "$.?" &echo,%sx%
pause&exit/bCOPY

TOP

给楼主发个C ,编译后直接带上参数运行就行了 ,速度飞快
#include <stdio.h>
#include <windows.h>
#pragma comment(lib, "shell32")
int main(){
int argc;
void **argv;
unsigned char c[8192]={0};
int n=0;
argv=(void **)CommandLineToArgvW(GetCommandLineW(), &argc);
if(argc>1){
for(int i=1;i<argc;i++){
WideCharToMultiByte(CP_UTF8,0,argv[i],-1,c,sizeof(c),NULL,NULL);
for(unsigned int j=0;*(c+j);j++)printf("%02X ",*(c+j));
printf("\b\n");
}}
LocalFree(argv);
return 0;
}COPY

TOP

返回列表