批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程
[批处理文件精品]批处理版照片整理器[批处理文件精品]纯批处理备份&还原驱动在线第三方下载
返回列表 发帖

编解码工具coder.exe 1.1

本帖最后由 went 于 2021-1-11 23:52 编辑

对写的字符串处理函数进行了封装,提供以下功能:
    1.编码转换
    2.文件编码查看
    3.URL编解码
    4.base64编解码
    以上功能均支持处理字符串和文件,可能会增加新功能
1.10添加功能,查看文件编码
1.11添加功能,支持管道

使用方法:
  1. 编码解码工具(Code By went.)
  2. coder.exe 用法:
  3.           转换工具   -convert <cp1> <cp2> -<string|file> [<str|filePath>|管道]
  4.           查看编码   -show    -action <getcoder> -<file> [<filePath>|管道]
  5.           url工具    -url     -action <decoder|encoder> -<string|file> [<str|filePath>|管道]
  6.           base64工具 -base64  -action <decoder|encoder> -<string|file> [<str|filePath>|管道]
  7.   例子:
  8.   coder -show -action getcoder -file "0.txt"
  9.          查看文件编码 [ ANSI | UTF-8 | UTF-8_BOM | UTF-16_BE | UTF-16_LE ]
  10.   coder -convert 0 65001 -string "你好,世界!"
  11.          字符串编码转换 ansi -> utf8 [浣犲ソ,涓栫晫!]
  12.   coder -convert 65001 0 -file "1.txt"
  13.          文件编码转换 utf8 -> ansi
  14.   coder -url -action decoder -string "%73%64%2F%E4%BD%A0%E5%A5%BD%21%2F%31%32%33"
  15.          字符串URL解码 [sd/你好!/123]
  16.   coder -url -action encoder -file "2.txt"
  17.          文件URL编码
  18.   coder -base64 -action encoder -string "你好世界!1234"
  19.          字符串base64编码 [xOO6w8rAvechMTIzNA==]
  20.   coder -base64 -action decoder -string "xOO6w8rAvechMTIzNA=="
  21.          字符串base64解码 [你好世界!1234]
  22.   coder -base64 -action encoder -file "3.png" >"base64.txt"
  23.           文件base64编码,保存到base64.txt
  24.   coder -base64 -action decoder -file "base64.txt" >"4.png"
  25.           文件base64解码,生成4.png
  26.   使用管道输入,例子:
  27.   echo 你好世界!1234| coder -base64 -action encoder -string
  28.        管道输入字符串base64编码 [xOO6w8rAvechMTIzNA==]
  29.   for %i in (*.png) do ( echo %i| coder -base64 -action encoder -file >"%i.txt" )
  30.        对当前路径下所有png文件base64进行编码,生成txt
复制代码
exe和源代码
附件: 您需要登录才可以下载或查看附件。没有帐号?注册

本帖最后由 went 于 2021-1-9 18:50 编辑

32位汇编核心代码
  1. ;**********************************************************************************************
  2. ;
  3. ; 字符串处理函数 Code by went
  4. ;
  5. ;**********************************************************************************************
  6. IFNDEF STRING_ASM
  7. STRING_ASM EQU 1
  8. .CODE
  9. ;**********************************************************************************************
  10. ;查找字符索引 从0开始
  11. ;[字符串指针, 要查找的字符,TRUE:查找第一个 FALSE:查找最后一个]
  12. ;返回值 查找返回索引,未找到返回-1
  13. _GetCharIndex PROC,_lpszSrc:dword,_bChar:byte,_bFirst:dword
  14. LOCAL _dwOffset,_dwMax
  15. pushad
  16. INVOKE lstrlen,_lpszSrc
  17. mov _dwMax,eax ;设置最大查找次数
  18. mov _dwOffset,-1 ;索引置 -1
  19. mov dl,_bChar ;设置查找的字符
  20. cmp _bFirst,FALSE
  21. je @rev
  22. mov esi,_lpszSrc ;顺序查找
  23. mov ecx,0 ;偏移置 0
  24. cld
  25. jmp @find
  26. @rev: ;倒序查找
  27. mov ecx,_dwMax ;偏移置 _dwMax
  28. mov esi,_lpszSrc
  29. add esi,_dwMax
  30. std
  31. @find: ;开始查找
  32. cmp _dwMax,0 ;字符查找完成,退出
  33. je @ret
  34. dec _dwMax ;最大查找次数 -1
  35. cmp byte PTR [esi],dl
  36. je @ok ;找到 -> ok
  37. cmp _bFirst,FALSE
  38. je @F
  39. inc esi
  40. inc ecx
  41. jmp @find ;顺序查找,esi +1 ,ecx +1,重复
  42. @@:
  43. dec esi
  44. dec ecx
  45. jmp @find ;倒序查找,esi -1, ecx -1,重复
  46. @ok:
  47. cmp ecx,0
  48. je @set
  49. cmp _bFirst,FALSE
  50. jmp @set
  51. inc ecx
  52. @set:
  53. mov _dwOffset,ecx ;成功,设置索引
  54. @ret:
  55. popad
  56. cld
  57. mov eax,_dwOffset
  58. ret
  59. _GetCharIndex ENDP
  60. ;----------------------------------------------------------------------------------------------
  61. ;获取子字符串
  62. ;[buffer指针, 源字符串指针, 开始索引(0开始), 字符串长度]
  63. _GetSubString PROC,_lpBuffer:dword,_lpStr:dword,_dwStartIndex:dword,_dwSubLen:dword
  64. pushad
  65. mov esi,_lpStr
  66. add esi,_dwStartIndex
  67. mov edi,_lpBuffer
  68. mov ecx,_dwSubLen
  69. rep movsb
  70. mov byte PTR [edi],0
  71. popad
  72. ret
  73. _GetSubString ENDP
  74. ;----------------------------------------------------------------------------------------------
  75. ;获取文件名,含扩展名
  76. ;[文件路径字符串指针,文件名buffer]
  77. ;返回值 EAX = 成功写入buffeer的字节数
  78. _GetFileName PROC,_lpszFile:dword,_lpBuffer:dword
  79. LOCAL _dwLen
  80. pushad
  81. mov _dwLen,0
  82. cmp _lpBuffer,NULL
  83. je @ret
  84. mov esi,_lpszFile
  85. INVOKE lstrlen,_lpszFile
  86. push eax
  87. mov ecx,eax
  88. add esi,eax
  89. std
  90. dec esi
  91. @find:
  92. lodsb
  93. cmp al,'\'
  94. je @done
  95. cmp al,'/'
  96. je @done
  97. cmp al,0
  98. je @done
  99. inc _dwLen
  100. jmp @find
  101. @done:
  102. cld
  103. add esi,2
  104. pop ecx
  105. mov edi,esi
  106. sub edi,_lpszFile
  107. sub ecx,edi
  108. mov edi,_lpBuffer
  109. rep movsb
  110. mov byte ptr [edi],0
  111. @ret:
  112. popad
  113. mov eax,_dwLen
  114. ret
  115. _GetFileName ENDP
  116. ;----------------------------------------------------------------------------------------------
  117. ;字符串编码转换
  118. ;[源字符串指针,源字符串编码(CP_XXX),保存转换后的字符串buffer的指针,目标字符串编码(CP_XXX),buffer长度]
  119. ;返回值 : EAX = 成功写入buffeer的字节数
  120. _ConvertString PROC,_lpszSrc:dword,_dwSrcType:dword,_lpBuffer:dword,_dwTagType:dword,_dwBufSize:dword
  121. LOCAL _dwWcharNum,_dwSize,_hHeap,_lpWStr
  122. pushad
  123. ;获取默认堆
  124. INVOKE GetProcessHeap
  125. mov _hHeap,eax
  126. ;源字符串转Unicode
  127. INVOKE MultiByteToWideChar,_dwSrcType,0,_lpszSrc,-1,NULL,0
  128. mov _dwWcharNum,eax
  129. mov edx,2
  130. mul edx
  131. inc eax
  132. mov _dwSize,eax ;获取Unicode字符串需要字节长度
  133. INVOKE HeapAlloc,_hHeap,HEAP_NO_SERIALIZE or HEAP_ZERO_MEMORY,_dwSize
  134. mov _lpWStr,eax   ;为Unicode字符串申请堆内存
  135. ;_dwSrcType -> Unicode
  136. INVOKE MultiByteToWideChar,_dwSrcType,0,_lpszSrc,-1,_lpWStr,_dwSize
  137. ;Unicode转目标字符串
  138. INVOKE WideCharToMultiByte,_dwTagType,0,_lpWStr,_dwWcharNum,_lpBuffer,_dwBufSize,NULL,NULL
  139. mov _dwSize,eax
  140. ;释放堆内存
  141. INVOKE HeapFree,_hHeap,HEAP_NO_SERIALIZE,_lpWStr
  142. popad
  143. mov eax,_dwSize
  144. ret
  145. _ConvertString ENDP
  146. ;----------------------------------------------------------------------------------------------
  147. ;URL 编码
  148. ;[源字符串指针,保存转换后的字符串buffer的指针,buffer长度]
  149. ;[EAX = 成功写入buffeer的字节数(不含0)]
  150. _UrlEncoder PROC,_lpszStr:dword,_lpBuffer:dword,_dwBufSize:dword
  151. LOCAL _dwWcharSize,_hHeap,_dwLen
  152. LOCAL _lpUTF8Str,_dwUtf8Size,_buf[3]:BYTE
  153. pushad
  154. ;获取默认堆
  155. INVOKE GetProcessHeap
  156. mov _hHeap,eax
  157. INVOKE lstrlen,_lpszStr
  158. mov edx,3
  159. mul edx
  160. mov _dwUtf8Size,eax
  161. INVOKE HeapAlloc,_hHeap,HEAP_NO_SERIALIZE or HEAP_ZERO_MEMORY,_dwUtf8Size
  162. mov _lpUTF8Str,eax   ;为UTF8字符串申请堆内存
  163. ;ANSI转UTF8
  164. INVOKE _ConvertString,_lpszStr,CP_ACP,_lpUTF8Str,CP_UTF8,_dwUtf8Size
  165. @init:
  166. mov _dwLen,0
  167. mov esi,_lpUTF8Str
  168. mov edi,_lpBuffer
  169. ;检查_dwBufSize
  170. cmp eax,0
  171. je @ret ;UTF8转换失败,退出
  172. dec eax
  173. mov edx,3
  174. mul edx
  175. inc eax
  176. cmp eax,_dwBufSize
  177. ja @ret ;长度不够,退出
  178. cld
  179. @copy:
  180. lodsb
  181. cmp al,0
  182. je @ret
  183. mov byte PTR [edi],'%' ;添加 %
  184. inc edi
  185. @@:
  186. movzx eax,al
  187. INVOKE wsprintf,ADDR _buf,$TZO('%2X'),eax
  188. push esi
  189. lea esi,_buf
  190. mov ecx,eax
  191. rep movsb ;复制十六进制数据
  192. pop esi
  193. add _dwLen,3
  194. jmp @copy
  195. @ret:
  196. mov byte PTR [edi],0 ;末尾加0
  197. popad
  198. mov eax,_dwLen
  199. ret
  200. _UrlEncoder ENDP
  201. ;----------------------------------------------------------------------------------------------
  202. ;URL 解码
  203. ;[源字符串指针,保存转换后的字符串buffer的指针,buffer长度]
  204. ;[EAX = 成功写入buffeer的字节数(不含0)]
  205. _UrlDecoder PROC,_lpszStr:dword,_lpBuffer:dword,_dwBufSize:dword
  206. LOCAL _dwSize,_hHeap,_lpUTF8Str
  207. LOCAL _buf[3]:BYTE
  208. pushad
  209. INVOKE GetProcessHeap
  210. mov _hHeap,eax
  211. INVOKE lstrlen,_lpszStr
  212. mov _dwSize,eax
  213. ;获取UTF8字符串
  214. INVOKE HeapAlloc,_hHeap,HEAP_NO_SERIALIZE or HEAP_ZERO_MEMORY,_dwSize
  215. mov _lpUTF8Str,eax   ;为UTF8字符串申请堆内存
  216. mov esi,_lpszStr
  217. mov edi,_lpUTF8Str
  218. mov ecx,_dwSize
  219. cld
  220. mov ecx,0
  221. @cmp:
  222. lodsb
  223. cmp al,0 ;AL = 0 结束
  224. je @convert
  225. cmp al,'%' ;AL = '%' ?
  226. je @copy2 ;是 则复制2个字符到_buf
  227. @copy1:
  228. ;$PT <ENDL,'COPY 1'>
  229. stosb ;否 则直接复制一个字符到_buf
  230. jmp @cmp
  231. @copy2:
  232. cmp byte ptr [esi],0
  233. je @copy1 ;下个字符为0,复制AL
  234. cmp byte ptr [esi],'%'
  235. je @copy1 ;下个字符为%,复制AL
  236. cmp byte ptr [esi],'0'
  237. jl @copy1 ;下个字符 < '0',复制AL
  238. cmp byte ptr [esi],'9'
  239. jle @F ;'0' <= 下个字符 <= '9' @F
  240. cmp byte ptr [esi],'A'
  241. jl @copy1 ;'9' < 下个字符 < 'A',复制AL
  242. cmp byte ptr [esi],'F'
  243. ja @copy1 ;下个字符 > 'F',复制AL
  244. @@:
  245. cmp byte ptr [esi + 1],0
  246. je @copy1
  247. cmp byte ptr [esi + 1],'%'
  248. je @copy1
  249. cmp byte ptr [esi + 1],'0'
  250. jl @copy1
  251. cmp byte ptr [esi + 1],'9'
  252. jle @F
  253. cmp byte ptr [esi + 1],'A'
  254. jl @copy1
  255. cmp byte ptr [esi + 1],'F'
  256. ja @copy1 ;下下个字符 > 'F',复制AL
  257. @@:
  258. ;$PT <ENDL,'COPY 2'>
  259. push edi
  260. lea edi,_buf
  261. mov ecx,2
  262. rep movsb ;从_lpszStr复制2个字符到_buf
  263. mov byte ptr [edi],0
  264. ;$PT <ENDL,'1'>
  265. INVOKE _StringToInt,ADDR _buf,16 ;从_buf读取一个int数字
  266. ;$PT <ENDL,'2'>
  267. pop edi
  268. stosb ;int数字存储到_lpUTF8Str
  269. jmp @cmp
  270. @convert:
  271. ;$PT <ENDL,'CONVER'>
  272. mov byte PTR [edi],0
  273. ;UTF8转ANSI
  274. INVOKE _ConvertString,_lpUTF8Str,CP_UTF8,_lpBuffer,CP_ACP,_dwBufSize
  275. mov _dwSize,0
  276. cmp eax,0
  277. je @F
  278. dec eax
  279. mov _dwSize,eax
  280. jmp @close
  281. @@:
  282. mov esi,_lpBuffer
  283. mov byte PTR [esi],0
  284. @close:
  285. INVOKE HeapFree,_hHeap,HEAP_NO_SERIALIZE,_lpUTF8Str
  286. @ret:
  287. popad
  288. mov eax,_dwSize
  289. ret
  290. _UrlDecoder ENDP
  291. ;----------------------------------------------------------------------------------------------
  292. ;Base64编码
  293. ;[源字节数据指针,源数据长度,数据buffer指针,buffer长度]
  294. ;返回值 EAX=写入buffer字节数据(不含0)
  295. _Base64Encoder PROC,_lpData:dword,_dwSize:dword,_lpBuffer:dword,_dwBufSize:dword
  296. LOCAL _dwValue,_dwRet,_dwCount,_dwLast,_bKey:byte
  297. pushad
  298. @init:
  299. ;$PT <ENDL,'总长度: '>
  300. ;INVOKE _PrintDec,_dwSize
  301. mov eax,_dwSize
  302. mov edx,0
  303. mov ebx,3
  304. div ebx
  305. mov _dwCount,eax ;_dwCount = 3个一组,一共多少组
  306. mov _dwLast,edx ;_dwLast = 最后剩下多少个字节
  307. mov esi,_lpData
  308. mov _dwRet,0
  309. mov _dwValue,0
  310. mov edi,_lpBuffer
  311. ;$PT <ENDL,'组数(n/3): '>
  312. ;INVOKE _PrintDec,_dwCount
  313. ;$PT <'  剩下字符: '>
  314. ;INVOKE _PrintDec,_dwLast
  315. @read3:
  316. ;读取3个字节到_dwValue
  317. cmp _dwCount,0
  318. je @readLast
  319. mov ecx,3 ;字节计数
  320. mov edx,4 ;循环计数
  321. @set:
  322. ;$PT <ENDL,'当前组数: '>
  323. ;INVOKE _PrintDec,_dwCount
  324. ;$PT <ENDL,'  读取字符:'>
  325. ;INVOKE _PrintDec,ecx
  326. push edi
  327. lea edi,_dwValue
  328. mov eax,3
  329. sub eax,ecx
  330. add edi,eax ;保证设置到_dwValue最高位
  331. ;按内存顺序设置_dwValue高3个字节
  332. @load:
  333. lodsb
  334. mov byte ptr [edi + ecx],al
  335. loop @load
  336. ;$PT <' _dwValue: '>
  337. ;INVOKE _PrintDec,_dwValue
  338. ;$PT '   '
  339. ;_dwValue循环左移6位,共4次
  340. pop edi
  341. mov eax,_dwValue
  342. @shl:
  343. cmp edx,0
  344. je @next_group
  345. ;$PT <' '>
  346. rol eax,6
  347. mov bl,al
  348. and bl,00111111b ;高2位清零
  349. movzx ebx,bl
  350. ;INVOKE _PrintDec,ebx
  351. ;$PT '->'
  352. mov _bKey,bl ;开始判断范围,设置_bKey
  353. cmp bl,26
  354. jl @A_Z
  355. cmp bl,52
  356. jl @a_z
  357. cmp bl,62
  358. jl @0_9
  359. cmp bl,62
  360. je @62
  361. mov _bKey,'+'
  362. cmp bl,63
  363. je @63
  364. mov _bKey,0 ;超出映射表字符,填充0
  365. jmp @next
  366. @63:
  367. mov _bKey,'/'
  368. jmp @next
  369. @62:
  370. mov _bKey,'+'
  371. jmp @next
  372. @A_Z:
  373. sub _bKey,0
  374. add _bKey,'A'
  375. jmp @next
  376. @a_z:
  377. sub _bKey,26
  378. add _bKey,'a'
  379. jmp @next
  380. @0_9:
  381. sub _bKey,52
  382. add _bKey,'0'
  383. jmp @next
  384. @next:
  385. mov al,_bKey
  386. mov byte ptr [edi],al
  387. movzx ebx,al
  388. ;INVOKE _PrintDec,ebx
  389. inc edi
  390. dec edx
  391. inc _dwRet
  392. mov ebx,_dwBufSize
  393. dec ebx
  394. cmp _dwRet,ebx
  395. jae @zero
  396. jmp @shl
  397. @next_group:
  398. cmp _dwCount,-1 ;-1表示读取最后剩下的字节结束
  399. je @ret
  400. dec _dwCount
  401. jmp @read3
  402. @readLast:
  403. ;读取最后剩下的字节
  404. cmp _dwLast,0
  405. je @ret
  406. ;$PT <ENDL,'LAST '>
  407. ;INVOKE _PrintDec,_dwLast
  408. ;$PT '  '
  409. ;INVOKE _PrintString,esi
  410. mov _dwCount,-1
  411. mov _dwValue,0
  412. mov ecx,_dwLast ;字节计数
  413. cmp ecx,1
  414. jne @F
  415. mov edx,2 ;剩下1个字节,设置2个Base64字符
  416. jmp @set
  417. @@:
  418. mov edx,3 ;剩下2个字节,设置3个Base64字符
  419. jmp @set ;跳转到@set设置_dwNum
  420. @ret:
  421. cmp _dwLast,0
  422. je @zero
  423. mov ecx,3
  424. sub ecx,_dwLast
  425. add _dwRet,ecx
  426. mov esi,$TZO('===')
  427. rep movsb ;填充'='
  428. @zero:
  429. mov byte ptr [edi],0 ;末尾加0
  430. popad
  431. mov eax,_dwRet
  432. ret
  433. _Base64Encoder ENDP
  434. ;----------------------------------------------------------------------------------------------
  435. ;Base64解码
  436. ;[源base64数据指针,源数据长度,解码数据buffer指针,buffer长度]
  437. ;返回值 [EAX=成功写入buffeer的字节数]
  438. _Base64Decoder PROC,_lpData:dword,_dwSize:dword,_lpBuffer:dword,_dwBufSize:dword
  439. LOCAL _dwValue,_dwCount,_dwLast,_dwRet,_dwZero
  440. pushad
  441. @init:
  442. mov _dwZero,0 ;记录填充0的个数
  443. ;$PT <ENDL,'字符总数:'>
  444. ;INVOKE _PrintDec,_dwSize ;源数据长度
  445. ;$PT <ENDL,'组数(n/4): '> ;分组 4个Base64字符为1组
  446. mov edx,0
  447. mov eax,_dwSize
  448. mov ebx,4
  449. div ebx
  450. mov _dwCount,eax
  451. mov _dwLast,edx
  452. ;INVOKE _PrintDec,_dwCount
  453. ;$PT <ENDL,'剩余字符:'>
  454. ;INVOKE _PrintDec,_dwLast
  455. mov esi,_lpData
  456. mov edi,_lpBuffer
  457. mov _dwRet,0
  458. @read4:
  459. cmp _dwCount,0
  460. je @ret
  461. ;$PT <ENDL,'读取字符到EBX:'>
  462. mov ecx,4
  463. ;INVOKE _PrintDec,ecx
  464. mov ebx,0 ;EBX保存当前解码数据 [XXX:00000000]
  465. add esi,3 ;ESI指向当前位置后第4个字符
  466. @load:
  467. cmp ecx,0
  468. je @set
  469. ;$PT ' '
  470. mov al,byte ptr [esi] ;加载base64字符 value
  471. movzx eax,al
  472. ;INVOKE _PrintDec,eax
  473. ;$PT '->' ;base64字符映射 value -> key
  474. cmp al,'='
  475. je @0
  476. cmp al,'+'
  477. je @62
  478. cmp al,'/'
  479. je @63
  480. cmp al,'9'
  481. jle @0_9
  482. cmp al,'Z'
  483. jle @A_Z
  484. cmp al,'z'
  485. jle @a_z
  486. @0:
  487. mov al,0 ;非映射表字符,填充0
  488. inc _dwZero
  489. jmp @next
  490. @62:
  491. mov al,62
  492. jmp @next
  493. @63:
  494. mov al,63
  495. jmp @next
  496. @A_Z:
  497. sub al,'A'
  498. add al,0
  499. jmp @next
  500. @a_z:
  501. sub al,'a'
  502. add al,26
  503. jmp @next
  504. @0_9:
  505. sub al,'0'
  506. add al,52
  507. jmp @next
  508. @next:
  509. movzx eax,al
  510. ;INVOKE _PrintDec,eax
  511. mov bl,al ;每读取一个字符,设置到bl
  512. ror ebx,6 ;EBX循环右移6位,低6位->高6位
  513. dec ecx
  514. dec esi ;ESI指向上个字符
  515. jmp @load
  516. @set:
  517. ;$PT ' EBX:'
  518. ;INVOKE _PrintDec,ebx
  519. mov _dwValue,ebx ;当前转换的3字节数据存到_dwValue
  520. push esi ;ESI备份
  521. ;$PT ' '
  522. lea esi,_dwValue
  523. add esi,3
  524. mov ecx,3
  525. @copy:
  526. mov al,byte ptr [esi]
  527. mov byte ptr [edi],al
  528. dec esi
  529. inc edi
  530. inc _dwRet
  531. mov eax,_dwBufSize
  532. dec eax
  533. cmp _dwRet,eax
  534. jl @F
  535. pop esi ;长度超出buffer长度,堆栈平衡,退出
  536. jmp @ret
  537. @@:
  538. loop @copy
  539. pop esi
  540. add esi,5 ;ESI归位,指向未读取字符开始位置
  541. dec _dwCount
  542. jmp @read4
  543. @ret:
  544. mov byte ptr [edi],0 ;末尾加零
  545. popad
  546. mov eax,_dwRet ;设置返回值
  547. sub eax,_dwZero ;减去填充0的字节数
  548. ret
  549. _Base64Decoder ENDP
  550. ;----------------------------------------------------------------------------------------------
  551. ENDIF
复制代码
3

评分人数

TOP

回复 1# went

用汇编写的,太厉害了啊。

TOP

本帖最后由 went 于 2021-1-10 23:50 编辑

添加功能,获取文件编码,函数如下
  1. ;获取文件编码
  2. ;[文件路径字符串指针,接收编码字符串buffer]
  3. ;返回值 EAX=Last Error(非0表示失败)
  4. _GetFileCoder PROC,_lpszPath:dword,_lpBuffer:dword
  5. LOCAL _dwRet,_hFile,_hFileMap,_lpData,_dwLen,_dwOne
  6. pushad
  7. ;创建文件映射
  8. INVOKE _FileToMapping,_lpszPath,ADDR _hFile,ADDR _hFileMap,ADDR _lpData,ADDR _dwLen
  9. ;错误处理
  10. mov _dwRet,eax
  11. cmp eax,0
  12. jne @ret
  13. @init:
  14. mov esi,_lpData
  15. ;开始判断编码
  16. ;utf-16_LE  [FF FE]
  17. cmp word ptr [esi],0FEFFh
  18. je @utf_16_le
  19. ;utf-16_BE [FE FF]
  20. cmp word ptr [esi],0FFFEh
  21. je @utf_16_be
  22. ;utf-8_BOM [EF BB BF]
  23. mov eax,dword ptr [esi]
  24. and eax,0BFBBEFh ;EAX最高字节清零
  25. cmp eax,0BFBBEFh
  26. je @utf_8_bom
  27. ;判断是否符合UTF-8编码
  28. @read:
  29. ;$PT <ENDL,'_dwLen:'>
  30. ;INVOKE _PrintDec,_dwLen
  31. cmp _dwLen,0
  32. jle @utf_8 ;字节全部检查完成,符合UTF-8编码,判定为UTF-8
  33. lodsb
  34. mov _dwOne,0
  35. dec _dwLen ;总字节数减1
  36. ;检查当前字节高位1的个数
  37. mov ecx,8
  38. @shl:
  39. shl al,1
  40. jnc @F           ;未进位则是0,结束检查
  41. inc _dwOne
  42. loop @shl
  43. @@:
  44. cmp _dwOne,0
  45. ja @F
  46. dec _dwLen                     ;最高位是0,进行下一轮检查
  47. jmp @read
  48. @@:
  49. ;检查接着的_dwOne个字节高2位是否为10
  50. dec _dwOne
  51. ;$PT <ENDL,'当前需检查字节数(不含本身):'>
  52. ;INVOKE _PrintDec,_dwOne
  53. mov ecx,_dwOne
  54. @check:
  55. cmp ecx,0
  56. je @read ;当前[1+_dwOne]个字节符合UTF-8编码,继续检查下一个字节
  57. lodsb
  58. and al,11000000b         ;AL低6位清零
  59. cmp al,10000000b         ;检查高2位是否为10
  60. jne @ansi ;找到一个不是10的,则不符合UTF-8,是ANSI编码
  61. dec _dwLen                     ;总字节数减1
  62. dec ecx ;_dwOne减1
  63. jmp @check
  64. @ansi:
  65. INVOKE lstrcat,_lpBuffer,$TZO('ANSI')
  66. jmp @ret
  67. @utf_16_le:
  68. INVOKE lstrcat,_lpBuffer,$TZO('UTF-16_LE')
  69. jmp @ret
  70. @utf_16_be:
  71. INVOKE lstrcat,_lpBuffer,$TZO('UTF-16_BE')
  72. jmp @ret
  73. @utf_8_bom:
  74. INVOKE lstrcat,_lpBuffer,$TZO('UTF-8_BOM')
  75. jmp @ret
  76. @utf_8:
  77. INVOKE lstrcat,_lpBuffer,$TZO('UTF-8')
  78. jmp @ret
  79. @ret:
  80. ;解除文件映射
  81. INVOKE _UnmapFileMapping,_lpData,_hFileMap,_hFile
  82. popad
  83. mov eax,_dwRet
  84. ret
  85. _GetFileCoder ENDP
复制代码

TOP

回复 4# went

当文件字节全是0-127范围内即每个最高位全是0时,文件ansi和utf8编码字节数据完全相同
coder.exe遵循notepad编码显示方式,把编码看成UTF-8

TOP

返回列表