找回密码
 注册
搜索
[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
查看: 32496|回复: 5

[数值计算] [分享]批处理大数的自由进制转换

[复制链接]
发表于 2012-6-3 18:02:12 | 显示全部楼层 |阅读模式
本帖最后由 qzwqzw 于 2012-6-4 18:39 编辑

由于某一个加解密算法的需要
需要对一串数字进行特殊进制的转换
此前类似的进制转换算法应该已经不少
就是不知道是否可以支持大数(>2^31)
所以参考了网上的一些资料
设计了一个大数的自由进制转换算法
%进制数列%限制了自由进制的支持上限

  1. @echo off & setlocal EnableDelayedExpansion
  2. set 大数=111111111111111111111111111111
  3. set from=2
  4. set to=10
  5. call :XConvert %大数% %from% %to% 结果
  6. echo [%from%进制] %大数%
  7. echo [%to%进制] %结果%
  8. pause
  9. goto :eof

  10. :XConvert - X进制大数N转换为指定Y进制(X/Y不大于62)
  11. :: 参考链接:http://www.cppblog.com/baby-fly/archive/2009/10/24/99362.html
  12. ::           http://www.cnblogs.com/phinecos/archive/2009/09/11/1564975.html
  13. setlocal EnableDelayedExpansion
  14. set 源数=%~1
  15. set 源进制=%~2
  16. set 目标进制=%~3
  17. set 返回值=%~4
  18. set 进制数列=0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
  19.         :XCloop1
  20.         set 位号=0
  21.         set 模=0
  22.         set 商=
  23.                 :XCloop2
  24.                 set 当前位=!源数:~%位号%,1!
  25.                 set 当前位值=-1
  26.                         :XCLoop3
  27.                         set /a 当前位值+=1
  28.                         if not "%当前位%"=="!进制数列:~%当前位值%,1!" goto :XCLoop3
  29.                 set /a 当前除数=模 * 源进制 + 当前位值
  30.                 set /a 当前商=当前除数 / 目标进制
  31.                 set 商=%商%!进制数列:~%当前商%,1!
  32.                 if "%商%"=="0" set 商=
  33.                 set /a 模=当前除数 %% 目标进制
  34.                 set /a 位号+=1
  35.                 if not "!源数:~%位号%,1!"=="" goto :XCloop2
  36.         if "%商%"=="" set 商=0
  37.         set 目标数=!进制数列:~%模%,1!%目标数%
  38.         set 源数=%商%
  39.         if not "%源数%"=="0" goto :XCloop1
  40. endlocal & set %返回值%=%目标数%
  41. goto :eof
复制代码

评分

参与人数 1技术 +1 收起 理由
Batcher + 1 感谢分享

查看全部评分

发表于 2012-6-4 08:44:46 | 显示全部楼层
感谢分享
发表于 2012-6-4 14:00:01 | 显示全部楼层
 楼主| 发表于 2012-6-4 18:45:55 | 显示全部楼层
回复 3# terse

在大数相除的算法上
你我都是模拟人工算法
只是我的算法多了源进制的变换

但是你的for实现
比我的goto loop实现高效的多
这可以归功与理论结合实践吧

另外上次贴出的代码存在两个严重问题
看来大家都没发现悄悄改了
发表于 2012-6-4 22:24:36 | 显示全部楼层
本帖最后由 neorobin 于 2012-6-4 22:34 编辑

找到几篇 其它 算法(主要是转换算法, 未讨论大数)的文章, 未读明白, 所以不知是否有优越性.

矩阵算法:
http://home.ccil.org/~remlaps/AlternateBaseConversionAlgorithms.pdf
http://home.ccil.org/~remlaps/DescribeAlgorithm.pdf
另一篇
http://www.dickgrune.com/Program ... ion/no_div_conv.pdf
发表于 2012-6-9 02:28:14 | 显示全部楼层
回复 4# qzwqzw
修改下 提升点效率 没完全测试

  1. @echo off&setlocal enabledelayedexpansion
  2. set S=111111111111111111111111111111
  3. set F=10
  4. set H=2
  5. set "str=0123456789abcdefghijklmnopqrstuvwxyz"
  6. echo [%f%进制] %S%
  7. FOR /L %%i in (0 1 35) do (   
  8.     set _!Str:~%%i,1!=%%i
  9.     set #!Str:~%%i,1!=!Str:~%%i,1!
  10. )
  11. :lp
  12. set Ln=&set R=0&set "Sn=!s!"
  13. for %%i in (4096 2048 1024 512 256 128 64 32 16)do if "!Sn:~%%i!" NEQ "" set/aLn+=%%i&set Sn=!Sn:~%%i!
  14. set Sn=!Sn!FEDCBA9876543210&set/aLn+=0x!Sn:~16,1!
  15. for /l %%i in (0,1,%Ln%) do (
  16.    for %%j in ("!S:~%%i,1!") do set num=!_%%~j!&if "!#%%~j!" neq %%j set /a num+=26
  17.    set/a "N=num+(R*F),R=N%%H,N/=H"
  18.    for %%j in (!N!) do set M=!M!!str:~%%j,1!
  19. )
  20.    set B=!str:~%r%,1!!B!
  21.    for /f "tokens=* delims=0" %%i in ("0!M!") do set "S=%%i"
  22.    if defined S set M=&goto lp
  23.    echo [%H%进制] !B!
  24. pause
复制代码

评分

参与人数 1PB +4 技术 +1 收起 理由
qzwqzw + 4 + 1 辛苦了!

查看全部评分

您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|手机版|小黑屋|批处理之家 ( 渝ICP备10000708号 )

GMT+8, 2026-3-18 02:00 , Processed in 0.019668 second(s), 8 queries , File On.

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表