[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
返回列表 发帖

【挑战】批处理实现摩尔斯码加解密

&&今天突然想起早几天看过的一部电影《风声》,里面描述的是地下**党是

如何利用摩尔斯密码跟敌人斗智斗勇的。在这里就不得简单先描述下摩尔斯码

了:摩尔斯码就是由双方以一定规律事先约定好的一组密码,它其实是由母本

和密文两部分组成的,而密文是根据母本上的排列规律来生成的。要破解这样

的密码,不得到母本基本上是不可能的。所以本人就想用批来模拟这一加密和

解密过程的实现。

    于是,我从网上找了个常用汉字简体表,再用批全部打乱生成了一个母本

homebook.txt如附件,母本中共有7176个汉字,分成了36版(部分),1-35版

每版10行,每行5列,每列4个字共200个字,36版也是如此排列,只是只有176

个字。而每个字就对应了一个四位的以“-”号格开的摩尔码(密文)如:段字

对应的摩尔码是30-9-1-1,30版9行1列第1个字(其实这一系列批处理比本挑战

题更麻烦)。

    现在我要求大家完成两个挑战:

    挑战一 根据homebook.txt将我给出的两组密文还原成原文(汉字),密

文如下(解密):

    1、17-5-5-1 8-2-2-4 17-10-4-4 9-8-3-1 3-2-5-3 21-7-1-2 15-9-1-3

    2、24-5-3-1 10-5-3-4 28-5-1-2 3-2-5-3 21-7-1-2 7-10-4-4 25-5-4-4

32-1-5-3 31-3-5-3 25-7-1-2 12-2-4-1 3-2-5-1

    挑战二 根据hommebook.txt将我给出的两句原文编译成密文(摩尔码),

原文如下(加密):

    1、我想他肯定知道这个地方有段好难走的路

    2、当敌人冲过来后你就拉响前面的警报

    要求不要生成临时文件,代码的效率要高,不得使用第三方工具,满分40

分,只完成一步不得分,以思路为重,酌情加分。

链接: https://pan.baidu.com/s/1SqJmvTQXSSuGdhpK7bmsJw 提取码: n3g7
2

评分人数

***共同提高***

此题挑战的绝对是批处理的执行效率,第2题实在想不出有什么高效的方法。
另外,30-9-1-1,30版9行1列第4个字,这里是否有误?
心绪平和,眼藏静谧。

TOP

以后可以用摩尔密码讲粗话不……


那个第一版的跟其他排的不一样,不统一哈
*******************************************************************
第1版
第1行: 蔡-町-铩-姬 摩-倡-词-洹 迪-龟-逵-骢 芄-粒-溧-唠 剸-炎-宜-淙


第2版
*******************************************************************
第1行: 砒-唳-珀-侉 珩-嗝-甥-锬 壅-初-邺-蹉 揍-琉-听-柲 憃-釉-链-椑

[ 本帖最后由 523066680 于 2009-11-23 08:52 编辑 ]

TOP

回复 3楼 的帖子

是我大意,已修正,不过也不影响挑战。
***共同提高***

TOP

这次想找人合作……
从来没有过合作写批处理的感觉,唉~

[ 本帖最后由 523066680 于 2009-11-23 14:21 编辑 ]

TOP

回复 4楼 的帖子

是这样子的,我认为排列如果固定,解密的时候可以直接计算
来得到该字所在的行,会省很多事

[ 本帖最后由 523066680 于 2009-11-23 16:39 编辑 ]

TOP

我想解析密文相对简单,而且效率也应该比加密要高,方法我也用的很常规:
  1. @echo off&setlocal enabledelayedexpansion
  2. set "str1=17-5-5-1 8-2-2-4 17-10-4-4 9-8-3-1 3-2-5-3 21-7-1-2 15-9-1-3"
  3. set "str2=24-5-3-1 10-5-3-4 28-5-1-2 3-2-5-3 21-7-1-2 7-10-4-4 25-5-4-4 32-1-5-3 31-3-5-3 25-7-1-2 12-2-4-1 3-2-5-1"
  4. for /l %%i in (1,1,2) do (
  5.    for %%j in (!str%%i!) do (
  6.       for /f "delims=- tokens=1-4" %%k in ("%%j") do (
  7.       call :search %%k %%l %%m %%n
  8.       )
  9.       set str=!str!!word!
  10.    )
  11. echo 密文:!str%%i!
  12. echo 原文:!str!&set str=
  13. )
  14. echo.&pause>nul
  15. :search
  16. set/a line=(%1-1)*13+%2+2
  17. set/a cols=%3+1
  18. set tmp=0
  19. for /f "delims=" %%i in (homebook.txt) do (
  20.    set/a tmp+=1
  21.    if !tmp!==!line! (
  22.       for /f "tokens=%cols%" %%j in ("%%i") do (
  23.          for /f "delims=- tokens=%4" %%k in ("%%j") do set word=%%k
  24.          goto eof
  25.       )
  26.    )
  27. )
  28. :eof
复制代码
而加密感觉相对麻烦点,而且里面的几个“函数”效率都较低,尤其是算列数用了echo|find 这种方法,效率大减。但是搞了一中午累得很,头有点大,不想再改了,看其他兄弟的了:
  1. @echo off&setlocal enabledelayedexpansion
  2. set "str1=我想他肯定知道这个地方有段好难走的路"
  3. set "str2=当敌人冲过来后你就拉响前面的警报"
  4. for /l %%i in (1,1,2) do (
  5.    for /f "delims=" %%j in ("!str%%i!") do (
  6.    set str=%%j&call :split
  7.    )
  8. echo 原文:!str%%i!
  9. echo 密文:!code!&set code=
  10. )
  11. echo.&pause>nul
  12. :split
  13. call :search !str:~0,1!
  14. set code=!code! !singlecode!
  15. set str=!str:~1!
  16. if "!str!"=="" goto eof
  17. goto split
  18. :search
  19. ::为了避开汉字表中的"第,行,版"三个字,搜索时采用-*或*-的格式
  20. findstr "\-%1" homebook.txt >nul&& call :transform \-%1
  21. findstr "%1\-" homebook.txt >nul&& call :transform %1\-
  22. goto eof
  23. :transform
  24. for /f "delims=: tokens=1-3" %%i in ('findstr/n "%1" homebook.txt') do (
  25.    set tmpstr=%1&set tmpstr=!tmpstr:\-=!
  26.    set 实际行数=%%i
  27.    set tmp=%%j&set tmp=!tmp:第=!&set 版块行数=!tmp:行=!
  28.    set count=
  29.    for %%l in (%%k) do (
  30.    set/a count+=1
  31.    echo %%l|find "!tmpstr!">nul&&set 版块列数=!count!&&call :计算列中序数 !
  32. tmpstr! %%l
  33.    )
  34. )
  35. if !实际行数! lss 15 set 版块数=1
  36. if !实际行数! geq 15 set/a 版块数=(!实际行数!-!版块行数!+12)/14
  37. set singlecode=!版块数!-!版块行数!-!版块列数!-!列中序数!
  38. goto eof
  39. :计算列中序数
  40. set tmpstr=%2&set tmpstr=!tmpstr:-= !
  41. set count=
  42. for %%i in (!tmpstr!) do (
  43. set/a count+=1
  44. if %%i==%1 set 列中序数=!count!
  45. )
  46. :eof
复制代码

[ 本帖最后由 wankoilz 于 2009-11-26 15:45 编辑 ]
2

评分人数

    • pusofalse: 学习了。PB + 5
    • batman: 不错,但效率真的很不尽人意PB + 15

TOP

要想提高效率,尽量不要用call,就本题而言,应该是不要出现一个call,
同时findstr也不要频繁使用。
***共同提高***

TOP

回复 7楼 的帖子

第一道题目还可以简化,应该活用skip。
第二道题目中,for %%i in (!tmpstr!) do (set/a count+=1&if %%i==%1 set 列中序数=!count!)
这个for语句出现了问题,因为每列有4个字,这个条件是已知的了,应该避免这种不必要的循环,用if ... else ... 代替。
心绪平和,眼藏静谧。

TOP

回复 9楼 的帖子

我也是看只有4个字,只循环4次,所以也就直接for了,是不大周密....

TOP

  1. @echo off&setlocal enabledelayedexpansion&set tmp=
  2. for /f "delims=:" %%i in ('findstr /n * homebook.txt') do (
  3. if defined tmp (
  4. set tmp=
  5. ) else (
  6. set tmp=1
  7. set/ai+=1
  8. set/ab!i!=%%i-1
  9. )
  10. )
  11. for %%i in (17-5-5-1 8-2-2-4 17-10-4-4 9-8-3-1 3-2-5-3 21-7-1-2 15-9-1-3) do set t=%%i&call :f !t:-= !
  12. echo.
  13. for %%i in (24-5-3-1 10-5-3-4 28-5-1-2 3-2-5-3 21-7-1-2 7-10-4-4 25-5-4-4 32-1-5-3 31-3-5-3 25-7-1-2 12-2-4-1 3-2-5-1) do set t=%%i&call :f !t:-= !
  14. echo.
  15. pause&goto :eof
  16. :f
  17. set/ak=b%1+%2
  18. set/at=%3*4-4+%4
  19. for /f "skip=%k% tokens=%t% delims=- " %%i in (homebook.txt) do (
  20. set/p=%%i<nul&goto :eof
  21. )
复制代码

[ 本帖最后由 Seter 于 2009-11-23 22:02 编辑 ]
1

评分人数

TOP

字典的文件名在开头定义,句子数量在开头定义


解密
  1. @echo off
  2. echo %time%
  3. setlocal enabledelayedexpansion
  4. set dict=dictionary.txt
  5. set codex=2
  6. set "code_1=17-5-5-1 8-2-2-4 17-10-4-4 9-8-3-1 3-2-5-3 21-7-1-2 15-9-1-3"
  7. set "code_2=24-5-3-1 10-5-3-4 28-5-1-2 3-2-5-3 21-7-1-2 7-10-4-4 25-5-4-4 32-1-5-3 31-3-5-3 25-7-1-2 12-2-4-1 3-2-5-1"
  8. for /l %%a in (1,1,%codex%) do (set all=!all! !code_%%a!)
  9. ::for遍历记录将要用到的行,避免每次都读取文本。
  10. for /f "tokens=1,*" %%a in (%dict%) do (
  11.    set now=%%a
  12.    if "!now:~0,1!!now:~-1!"=="第版" (set "na=!now:第=!" &set "na=!na:版=!")
  13.    if "!now:~0,1!!now:~-2!"=="第行:" (
  14.       set "nb=!now:第=!" &set "nb=!nb:行:=!"
  15.       for %%A in (!na!-!nb!) do (
  16.         if not "!all: %%A=!"=="!all!" (
  17.           set Line%%A=%%b
  18.         )
  19.       )
  20.    )
  21. )
  22. ::针对那两句
  23. for /l %%a in (1,1,%codex%) do (
  24.   for %%b in (!code_%%a!) do (
  25.      set "now=%%b" &set "now=!now:-= !"
  26.      set /a n=0
  27.      for %%c in (!now!) do (set /a n+=1 &set num_!n!=%%c)
  28.      set /a col=num_3*8-8+num_4*2-2
  29.      for %%d in (!num_1!-!num_2!) do (set now=!Line%%d!)
  30.      for %%d in (!col!) do (set /p=!now:~%%d,1!<nul)
  31.   )
  32.   echo,
  33. )
  34. echo %time%
  35. pause
复制代码
加密

  1. @echo off
  2. echo %time%
  3. setlocal enabledelayedexpansion
  4. set dict=dictionary.txt
  5. set /a sayx=2
  6. set "say_1=我想他肯定知道这个地方有段好难走的路"
  7. set "say_2=当敌人冲过来后你就拉响前面的警报"
  8. for /l %%a in (1,1,50) do (set one=111111!one!)
  9. for /l %%a in (1,1,%sayx%) do (
  10. set count=!say_%%a!#%one%
  11. set count=!count:~0,300!
  12. set count=!count:*#=!
  13. set /a count%%a=300!count:1=-1!-1-1
  14. for /l %%n in (0,1,!count%%a!) do (set "str_%%a=!str_%%a!!say_%%a:~%%n,1! ")
  15. set strx_%%a=!str_%%a!
  16. )
  17. set /a na=0
  18. ::for遍历记录将要用到的行,避免每次都读取文本。
  19. for /f "tokens=1,*" %%a in (%dict%) do (
  20.    set now=%%a
  21.    if "!now:~0,1!!now:~-1!"=="第版" (set /a na+=1,nb=0)
  22.    if "!now:~0,1!!now:~-2!"=="第行:" (
  23.       set /a nb+=1
  24.       set now=%%b
  25.       for /l %%A in (1,1,%sayx%) do (
  26.          for %%B in (!str_%%A!) do (
  27.          if not "!now:%%B=!"=="!now!" (
  28.              set count=!now:*%%B=!#%one%
  29.              set count=!count:~0,300!
  30.              set count=!count:*#=!
  31.              set /a count=300!count:1=-1!-1,count=40-count,nc=count/8+1,nd=count%%8+1,nd=nd/2
  32.              for %%C in (!na!-!nb!-!nc!-!nd!) do (
  33.                set strx_%%A=!strx_%%A:%%B=%%C!
  34.              )
  35.              set str_%%A=!str_%%A:%%B=!
  36.          )
  37.          )
  38.       )
  39.    )
  40. )
  41. for /l %%a in (1,1,%sayx%) do (echo !strx_%%a! &echo,)
  42. echo %time%
  43. pause
复制代码

[ 本帖最后由 523066680 于 2009-11-24 09:40 编辑 ]
2

评分人数

TOP

用call 的的方法之一

  1. @echo off&setlocal enabledelayedexpansion
  2. set sati=!time!
  3. set Ban=0
  4. for /f "tokens=* delims=*" %%a in (homebook.txt) do (
  5.         set str=%%a
  6.         if "!str:~-1!" equ "版" (set /a Ban+=1) else (
  7.                 for /f "tokens=1,2,*" %%b in ("!ban! !str:-=!") do (set Ban%%b=!Ban%%b!%%d@)
  8.         )
  9. )
  10. ::前面读取母本到变量
  11. for /f "tokens=*" %%a in (密文.txt) do (
  12.         set 原文=
  13.         for %%b in (%%a) do (
  14.                 for /f "tokens=1-4 delims=-" %%1 in ("%%b") do (
  15.                         set/a hang=%%2-1
  16.                         call :sub 原字 %%1 !hang! %%3 %%4
  17.                         set 原文=!原文!!原字!
  18.                 )
  19.         )
  20.         echo;!原文!
  21. )
  22. ::解密
  23. echo;!sati!
  24. echo;!time!
  25. set sati=!time!
  26. for /f "tokens=*" %%a in (原文.txt) do (
  27.         set sour=%%a
  28.         set/a z=8180,x=0,y=0
  29.         for /l %%a in (1,1,14) do (set/a "y=(z-x)/2+x"
  30.             for %%b in (!y!) do if "!sour:~%%b,1!" equ "" (set/a z=y) else (set/a x=y)
  31.         )
  32.         set 密文=
  33.         echo !sour! [!x!]
  34.         for /l %%b in (0,1,!x!) do (call :sub2 !sour:~%%b,1!)
  35.         echo;!密文!
  36. )
  37. ::加密
  38. echo;!sati!
  39. echo;!time!
  40. pause
  41. goto :eof
  42. :sub
  43. for /f "tokens=1-10 delims=@" %%0 in ("!Ban%2!") do (
  44.         for /f "tokens=1-5" %%1 in ("%%%3") do (
  45.                 set "str=@%%%4"
  46.                 set %1=!str:~%5,1!
  47.         )
  48. )
  49. goto :eof
  50. :sub2
  51. (
  52. for /l %%a in (1,1,!ban!) do (
  53.         if "!Ban%%a:%1=!" neq "!Ban%%a!" set str=!Ban%%a!&set zban=%%a
  54. )
  55. for /f "delims=%1" %%a in ("!str!") do (set str=%%a)
  56. set/a z=8180,x=0,y=0
  57. for /l %%a in (1,1,14) do (set/a "y=(z-x)/2+x"
  58.     for %%b in (!y!) do if "!str:~%%b,1!" equ "" (set/a z=y) else (set/a x=y)
  59. )
  60. set/a zhang=x/26+1,x=x%%26,zlie=x/5+1,zzhi=x%%5+1
  61. set 密文=!密文! !zban!-!zhang!-!zlie!-!zzhi!
  62. goto :eof)
复制代码

[ 本帖最后由 netbenton 于 2009-11-23 23:43 编辑 ]

TOP

没有call 的方法之一

  1. @echo off&setlocal enabledelayedexpansion
  2. set sati=!time!
  3. set Ban=0
  4. for /f "tokens=* delims=*" %%a in (homebook.txt) do (
  5. set str=%%a
  6. if "!str:~-1!" equ "版" (set /a Ban+=1) else (
  7.   for /f "tokens=1,2,*" %%b in ("!ban! !str:-=!") do (set Ban%%b=!Ban%%b!%%d@)
  8. )
  9. )
  10. ::前面读取母本到变量
  11. for /f "tokens=*" %%a in (密文.txt) do (
  12. set 原文=
  13. for %%b in (%%a) do (
  14.   for /f "tokens=1-4 delims=-" %%1 in ("%%b") do (
  15.    for /f "tokens=1-10 delims=@" %%0 in ("!Ban%%1!") do (
  16.     set v1=%%0&set v2=%%1&set v3=%%2&set v4=%%3&set v5=%%4&set v6=%%5&set v7=%%6&set v8=%%7&set v9=%%8&set v10=%%9
  17.    )
  18.    for /f "tokens=1-5" %%0 in ("!v%%2!") do (
  19.     set v1=%%0&set v2=%%1&set v3=%%2&set v4=%%3&set v5=%%4
  20.    )
  21.    set "str=@!v%%3!"
  22.    set 原文=!原文!!str:~%%4,1!
  23.   )
  24. )
  25. echo;!原文!
  26. )
  27. ::解密
  28. echo;!sati!
  29. echo;!time!
  30. set sati=!time!
  31. for /f "tokens=*" %%a in (原文.txt) do (
  32. set sour=%%a
  33. set/a z=8180,x=0,y=0
  34. for /l %%a in (1,1,14) do (set/a "y=(z-x)/2+x"
  35.      for %%b in (!y!) do if "!sour:~%%b,1!" equ "" (set/a z=y) else (set/a x=y)
  36. )
  37. set 密文=
  38. echo !sour! [!x!]
  39. for /l %%b in (0,1,!x!) do (
  40.   for %%c in ("!sour:~%%b,1!") do (
  41.    for /l %%d in (1,1,!ban!) do (
  42.     if "!Ban%%d:%%~c=!" neq "!Ban%%d!" set str=!Ban%%d!&set zban=%%d
  43.    )
  44.    for %%d in ("!str:*%%~c=!") do set "str=!str:%%~d=!"
  45.    
  46.    set/a z=1000,x=0,y=0
  47.    for /l %%a in (1,1,11) do (set/a "y=(z-x)/2+x"
  48.     for %%b in (!y!) do if "!str:~%%b,1!" equ "" (set/a z=y) else (set/a x=y)
  49.    )
  50.    set/a zhang=x/26+1,x=x%%26,zlie=x/5+1,zzhi=x%%5
  51.    set 密文=!密文! !zban!-!zhang!-!zlie!-!zzhi!
  52.   )
  53. )
  54. echo;!密文!
  55. )
  56. ::加密
  57. echo;!sati!
  58. echo;!time!
  59. pause
  60. goto :eof
复制代码

[ 本帖最后由 netbenton 于 2009-11-23 23:43 编辑 ]
3

评分人数

TOP

  1. @echo off&setlocal enabledelayedexpansion&set tmp=
  2. for /f "delims=:" %%i in ('findstr /n * homebook.txt') do (
  3. if defined tmp (
  4. set tmp=
  5. ) else (
  6. set tmp=1
  7. set/ai+=1
  8. set/a_%%i=!i!
  9. )
  10. )
  11. call :f 安
  12. pause&goto :eof
  13. :f
  14. for /f "tokens=1-2* delims=:第行" %%i in ('findstr /n /c:%1- homebook.txt') do set t=%%i&set k=%%j&set o=%%k
  15. for /f "tokens=1-2* delims=:第行" %%i in ('findstr /n /c:-%1 homebook.txt') do set t=%%i&set k=%%j&set o=%%k
  16. set o=!o:-= !
  17. set o=!o:%1=? - !
  18. set i=0&set s=1
  19. for %%i in (%o%) do (
  20. set/ai+=s
  21. if "%%i"=="-" set s=0
  22. )
  23. set/ai-=1
  24. set/ap=%i%%%4+1
  25. set/ai=i/4+1
  26. set/at=t-k
  27. set t=!_%t%!
  28. echo %t%-%k%-%i%-%p%
  29. goto :eof
复制代码
抱歉,没时间写句子了

TOP

返回列表