免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 3225 | 回复: 7
打印 上一主题 下一主题

[文本处理] 大家来找茬!请大家帮我看看这个uuencode编解码程序究竟错在哪里? [复制链接]

论坛徽章:
18
辰龙
日期:2014-05-21 21:01:4115-16赛季CBA联赛之深圳
日期:2016-12-23 13:51:3815-16赛季CBA联赛之北控
日期:2016-11-28 18:26:3815-16赛季CBA联赛之佛山
日期:2016-11-03 11:18:5815-16赛季CBA联赛之辽宁
日期:2016-07-10 16:09:4115-16赛季CBA联赛之江苏
日期:2016-02-20 23:09:202015亚冠之塔什干棉农
日期:2015-08-17 19:49:492015年亚洲杯之日本
日期:2015-04-30 01:24:342015年亚洲杯之约旦
日期:2015-04-01 00:37:182015年亚洲杯之沙特阿拉伯
日期:2015-03-02 15:55:40处女座
日期:2014-05-25 10:34:0020周年集字徽章-年
日期:2023-04-23 11:17:52
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2014-05-28 01:53 |只看该作者 |倒序浏览
本帖最后由 bikkuri 于 2014-05-28 09:48 编辑

大家好!
我有一个困扰我很长时间的问题请大家帮忙。
我写了一个uuencode的编码和解码程序。
uuencode的编码规则详见:http://zh.wikipedia.org/wiki/Uuencode
编码程序如下:
  1. #!/bin/sh
  2. uu_encode()
  3. {
  4. rm -f $encuu
  5. if [ -f /usr/bin/uuencode ] ; then
  6. for buff in $(hexdump -ve '1/1 "%x "'); do printf "\x$buff" >> $encuu; done
  7. uuencode $encuu $encuu|awk 'NR>2{print p}{p=$0}'
  8. rm -f $encuu
  9. else
  10. hexdump -ve '1/1 "%d "'|awk '{for(k=0;k*45<=NF;k++){m=(45*k+45<NF)?77:(NF+32-45*k);printf("%c",m);for(i=1;i<=m-32;i+=3){t=0;t=$(i+k*45)*256*256+$(i+k*45+1)*256+$(i+k*45+2);for(j=3;j>=0;j--){z=1;for(p=0;p<6*j;p++)z=z*2;c=(i+34-j<=m)?(int(t/z)+32):"`";if(c==32)c=96;printf("%c",c);t%=z}}printf"\n"}printf"`\n"}'
  11. fi
  12. }
  13. encuu=/tmp/uu.enc
  14. uu_encode
复制代码
解码程序如下:
  1. #!/bin/sh
  2. uu_decode()
  3. {
  4. if [ -f /usr/bin/uudecode ] ; then
  5. echo "begin 644 b" > $decuu
  6. awk NF >> $decuu
  7. echo "end" >> $decuu
  8. uudecode -o $outuu $decuu
  9. cat $outuu
  10. rm -f $decuu $outuu
  11. else
  12. local buff=""
  13. for buff in $(awk '{for(l=0;l<NR;l++){h=substr($0,1,1);$0=substr($0,2);if(h!="`"){while(length($0)>0){split(substr($0,1,4),a,"");$0=substr($0,5);t=0;for(i=3;i>=0;i--){for(c=32;c<96;c++){if(sprintf("%c",c)==a[4-i])break}z=1;for(p=0;p<6*i;p++)z=z*2;t=t+z*((a[4-i]=="`")?0:c-32)};for (j=2;j>=0;j--) if (a[4-j]!="`"){y=1;for(p=0;p<8*j;p++)y=y*2;printf("\\x%x",t/y);t%=y}}}}printf"\n"}');do printf "$buff";done
  14. fi
  15. }
  16. decuu=/tmp/uu.dec
  17. outuu=/tmp/uu.out
  18. uu_decode
复制代码
编码程序和解码程序中首先判断系统有没有自带的uuencode和uudecode命令,如果有的话,则直接使用系统自带的命令,如果没有的话,则用awk进行编码和解码运算。
因为用系统自带的命令执行效率远比用awk来运算要高,所以只有系统没有自带编解码命令的时候才用awk来编解码。
但是现在发现两者编解码出来的内容不一致!
  1. root@nbox:/tmp/test/uu# gzip -c uudecode_final.sh |./uuencode_final.sh
  2. M'XL(`/PXA5,"`UV2P7*;,!"&[WJ*C8HGD@T!8]?35I9SRS&'7&-/"[(((@08
  3. MD";!#.\>`;'K5B?MM[O__IK5MQL_5H7?I,B8WT<IRJ,D%'5()?`,7@*^:>JQ
  4. MPI@I"P=@H%-9("G2$G`L7U0!F_4:8@P[<&R5,2AZ?X7'!]A=P%0LBR.^@A=-
  5. MKP2G--J8<T9$^HN@^FWP,?$SDWDC45Z**(?8)`G'&"5E/=[!NG'(,/^VLXSD
  6. M/&#Y]O&)Y8L%[5+>F+C1-7$"=^DN*7."*Q)2IA*2WG#\!]/N/56Y)+DL7G1J
  7. MLW07T*ZI<J7)M<::NI&+\7]*WRG3=O!@0/$54SL;*,^CHR7!5R$3VY\;)@9/
  8. M=F13U:K0"<$S@5U!.8^>UYXZT+B6T6M_XLM1J;(BU78S5ZRR?2=^FH=VBEZ<
  9. MYH1,#7QT?A_\$MXJI/W0!23C(<L&`YDU`':Q8W%V^'IF^X_ZCWDVJK>\M>IG
  10. M6_O]Q^P#N]IO[;MFO.WMF7)X7^#^EK)C"1,`[`QKP)84$B4*]6A<'??U6V5_
  11. 6T9V-T+C%"['1W]^'/@%23X'>D@(`````
  12. `
  13. root@nbox:/tmp/test/uu#
  14. ------------------------------------------------------------------------------------------------
  15. root@dbox:/tmp/test/uu# gzip -c uudecode_final.sh |./uuencode_final.sh
  16. M'XL(`->]A%,"`UV2P7*;,!"&[WJ*C8HGD@T!8]?35I9SRS&'7&-/"[(((@08
  17. MD";!#.\>`;'K5B?MM[O__IK5MQL_5H7?I,B8WT<IRJ,D%'5()?`,7@*^:>JQ
  18. MPI@I"P=@H%-9("G2$G`L7U0!F_4:8@P[<&R5,2AZ?X7'!]A=P%0LBR.^@A=-
  19. MKP2G--J8<T9$^HN@^FWP,?$SDWDC45Z**(?8)`G'&"5E/=[!NG'(,/^VLXSD
  20. M/&#Y]O&)Y8L%[5+>F+C1-7$"=^DN*7."*Q)2IA*2WG#\!]/N/56Y)+DL7G1J
  21. MLW07T*ZI<J7)M<::NI&+\7]*WRG3=O!@0/$54SL;*,^CHR7!5R$3VY\;)@9/
  22. M=F13U:K0"<$S@5U!.8^>UYXZT+B6T6M_XLM1J;(BU78S5ZRR?2=^FH=VBEZ<
  23. MYH1,#7QT?A_\$MXJI/W0!23C(<L&`YDU`':Q8W%V^'IF^X_ZCWDVJK>\M>IG
  24. M6_O]Q^P#N]IO[;MFO.WMF7)X7^#^EK)C"1,`[`QKP)84$B4*]6A<'??U6V5_
  25. 6T9V-T+C%"['1W]^'/@%23X'>D@(`````
  26. `
  27. root@dbox:/tmp/test/uu#
复制代码
大家可以看到在nbox上是有自带的uuencode和uudecode命令的,所以nbox上应该是标准的uuencode编码结果。
dbox是没有自带的uuencode和uudecode命令的,所以dbox上是awk运算出来的编码结果。
两者乍一看非常相似,但是仔细看可以发现从第7个字符开始有细微的差异。
请大家帮忙看看我的程序错在什么地方呢?
谢谢了!

论坛徽章:
18
辰龙
日期:2014-05-21 21:01:4115-16赛季CBA联赛之深圳
日期:2016-12-23 13:51:3815-16赛季CBA联赛之北控
日期:2016-11-28 18:26:3815-16赛季CBA联赛之佛山
日期:2016-11-03 11:18:5815-16赛季CBA联赛之辽宁
日期:2016-07-10 16:09:4115-16赛季CBA联赛之江苏
日期:2016-02-20 23:09:202015亚冠之塔什干棉农
日期:2015-08-17 19:49:492015年亚洲杯之日本
日期:2015-04-30 01:24:342015年亚洲杯之约旦
日期:2015-04-01 00:37:182015年亚洲杯之沙特阿拉伯
日期:2015-03-02 15:55:40处女座
日期:2014-05-25 10:34:0020周年集字徽章-年
日期:2023-04-23 11:17:52
2 [报告]
发表于 2014-05-28 02:22 |只看该作者
awk编解码的部分大家看着可能比较累,我排一下版,来个局部特写。
编码部分:
  1. hexdump -ve '1/1 "%d "'|awk '{
  2. for(k=0;k*45<=NF;k++){
  3.         m=(45*k+45<NF)?77:(NF+32-45*k);
  4.         printf("%c",m);
  5.         for(i=1;i<=m-32;i+=3){
  6.                 t=0;
  7.                 t=$(i+k*45)*256*256+$(i+k*45+1)*256+$(i+k*45+2);
  8.                 for(j=3;j>=0;j--){
  9.                         z=1;
  10.                         for(p=0;p<6*j;p++)z=z*2;
  11.                         c=(i+34-j<=m)?(int(t/z)+32):"`";
  12.                         if(c==32)c=96;
  13.                         printf("%c",c);
  14.                         t%=z
  15.                 }
  16.         }
  17.         printf"\n"
  18. }
  19. printf"`\n"
  20. }
  21. '
复制代码
解码部分:
  1. for buff in $(awk '{
  2.         for(l=0;l<NR;l++){
  3.                 h=substr($0,1,1);
  4.                 $0=substr($0,2);
  5.                 if(h!="`"){
  6.                         while(length($0)>0){
  7.                                 split(substr($0,1,4),a,"");
  8.                                 $0=substr($0,5);
  9.                                 t=0;
  10.                                 for(i=3;i>=0;i--){
  11.                                         for(c=32;c<96;c++){
  12.                                                 if(sprintf("%c",c)==a[4-i])break
  13.                                         }
  14.                                         z=1;
  15.                                         for(p=0;p<6*i;p++)z=z*2;
  16.                                         t=t+z*((a[4-i]=="`")?0:c-32)
  17.                                 };
  18.                                 for(j=2;j>=0;j--)if(a[4-j]!="`"){
  19.                                         y=1;
  20.                                         for(p=0;p<8*j;p++)y=y*2;
  21.                                         printf("\\x%x",t/y);
  22.                                         t%=y
  23.                                 }
  24.                         }
  25.                 }
  26.         }
  27. printf"\n"
  28. }
  29. ');do printf "$buff";done
复制代码

论坛徽章:
32
处女座
日期:2013-11-20 23:41:20双子座
日期:2014-06-11 17:20:43戌狗
日期:2014-06-16 11:05:00处女座
日期:2014-07-22 17:30:47狮子座
日期:2014-07-28 15:38:17金牛座
日期:2014-08-05 16:34:01亥猪
日期:2014-08-18 13:34:25白羊座
日期:2014-09-02 15:03:55金牛座
日期:2014-11-10 10:23:58处女座
日期:2014-12-02 09:17:52程序设计版块每日发帖之星
日期:2015-06-16 22:20:002015亚冠之塔什干火车头
日期:2015-06-20 23:28:22
3 [报告]
发表于 2014-05-28 08:54 |只看该作者
不明觉厉~{:2_166:}

论坛徽章:
769
金牛座
日期:2014-02-26 17:49:58水瓶座
日期:2014-02-26 18:10:15白羊座
日期:2014-04-15 19:29:52寅虎
日期:2014-04-17 19:43:21酉鸡
日期:2014-04-19 21:24:10子鼠
日期:2014-04-22 13:55:24卯兔
日期:2014-04-22 14:20:58亥猪
日期:2014-04-22 16:13:09狮子座
日期:2014-05-05 22:31:17摩羯座
日期:2014-05-06 10:32:53处女座
日期:2014-05-12 09:23:11子鼠
日期:2014-05-21 18:21:27
4 [报告]
发表于 2014-05-28 11:20 |只看该作者
回复 3# yestreenstars
星辰大大都不明,我等只能绕道了。

   

论坛徽章:
32
处女座
日期:2013-11-20 23:41:20双子座
日期:2014-06-11 17:20:43戌狗
日期:2014-06-16 11:05:00处女座
日期:2014-07-22 17:30:47狮子座
日期:2014-07-28 15:38:17金牛座
日期:2014-08-05 16:34:01亥猪
日期:2014-08-18 13:34:25白羊座
日期:2014-09-02 15:03:55金牛座
日期:2014-11-10 10:23:58处女座
日期:2014-12-02 09:17:52程序设计版块每日发帖之星
日期:2015-06-16 22:20:002015亚冠之塔什干火车头
日期:2015-06-20 23:28:22
5 [报告]
发表于 2014-05-28 13:42 |只看该作者
回复 4# Herowinter
我主要是没耐心看,你可以试试~{:2_172:}

   

论坛徽章:
2
白羊座
日期:2013-11-18 19:52:42辰龙
日期:2014-09-07 07:46:06
6 [报告]
发表于 2014-05-28 15:40 |只看该作者
本帖最后由 damcool 于 2014-05-28 20:37 编辑
  1. #!/bin/bash

  2. ################################################################################
  3. # Function Name:   HELP_USAGE                                                   
  4. # Description:     Function to display the usage of the script                  
  5. # Parameters:      None                                                         
  6. # Return:          Help messages                                                
  7. # Called By:       Script Main Loop->Script Parameters' Handler                 
  8. # History:         2013-Dec-31 Initial Edition                       RobinHoo  
  9. ################################################################################

  10. function help_usage(){
  11. cat <<EOF
  12. Unix-to-Unix ENCODE & DECODE BASH SCRIPT
  13. Usage: $PROGNAME [OPTION]... [FILE]
  14.   -d, --decode Decode the UUEncoded file
  15.   -h, --help   Show current help message of the script usages
  16.    

  17. Please Report Script Bugs to $AUTHOR_MAIL
  18. EOF
  19. exit 1
  20. }

  21. function UUENCODE()
  22. {
  23.         which uuencode >/dev/null 2>&1 && uuencode "$FNAME" "$FNAME" 2>/dev/null && return
  24.         echo "begin $(stat -c %a "$FNAME") $(basename "$FNAME")"
  25.         hexdump -ve '3/1 "%d " "\n"' < "$FNAME"|awk 'BEGIN{for(i=33;i<96;i++)U64=sprintf("%s%c",U64,i);U64="`"U64}{k+=NF;t=$1*65536+$2*256+$3;for(j=3;j>=0;j--){c=(3-j<=NF)?substr(U64,int(t/2^(6*j))+1,1):"`";o=sprintf("%s%c",o,(c=="\0")?"_":c);t%=2^(6*j);if (length(o)>59) {printf"M%s\n",o;o=""}}}END{if(k%45>0)printf"%c%s\n",32+k%45,o;printf "`\nend\n"}'
  26. }

  27. function UUDECODE()
  28. {
  29.         local buff=""
  30.         which uudecode >/dev/null 2>&1 && uudecode -o - "$FNAME" && return
  31.         for buff in $(cat < "$FNAME"|awk 'BEGIN{for(i=33;i<96;i++)U64=sprintf("%s%c",U64,i);U64="`"U64}NR>1{if ($0=="`") exit;m=index(U64,substr($0,1,1));n=0;$0=substr($0,2);while(length()){split(substr($0,1,4),a,"");$0=substr($0,5);t=0;for(i=3;i>=0;i--) t=t+2^(6*i)*(index(U64,a[4-i])-1);for (i=2;i>=0;i--) if (++n<m){printf("\\x%x",t/2^(8*i));t=t%2^(8*i)}}printf"\n"}');do printf "$buff"; done
  32. }
  33. BASE_DIR=$(cd "$(dirname "$0")" && pwd)
  34. PROGNAME=$(basename "$0")
  35. AUTHOR_MAIL="robin.hoo@hotmail.com"
  36. DECODE=0;
  37. HELP=0;
  38. FNAME="";
  39. while [ $# -gt 0 ]
  40. do
  41.     case "$1" in
  42.     (-d)        DECODE=1;;
  43.     (-h)        HELP=1;;
  44.     (--decode)  DECODE=1;;
  45.     (--help)    HELP=1;;
  46.     (-*)        echo "$PROGNAME: error - unrecognized option or parameter $1" 1>&2; HELP=1;break;;
  47.     (*)         [ "$FNAME" != "" ] && echo "$PROGNAME: error - more than one file name " 1>&2 && HELP=1 && break || FNAME="$1";;
  48.     esac
  49.     shift
  50. done
  51. [ $# -gt 1 ] && HELP=1
  52. [ "$FNAME" == "" ] && FNAME="/dev/stdin"
  53. [ $HELP -eq 1 ] && help_usage
  54. [ $DECODE -eq 1 ] && UUDECODE || UUENCODE
复制代码

论坛徽章:
18
辰龙
日期:2014-05-21 21:01:4115-16赛季CBA联赛之深圳
日期:2016-12-23 13:51:3815-16赛季CBA联赛之北控
日期:2016-11-28 18:26:3815-16赛季CBA联赛之佛山
日期:2016-11-03 11:18:5815-16赛季CBA联赛之辽宁
日期:2016-07-10 16:09:4115-16赛季CBA联赛之江苏
日期:2016-02-20 23:09:202015亚冠之塔什干棉农
日期:2015-08-17 19:49:492015年亚洲杯之日本
日期:2015-04-30 01:24:342015年亚洲杯之约旦
日期:2015-04-01 00:37:182015年亚洲杯之沙特阿拉伯
日期:2015-03-02 15:55:40处女座
日期:2014-05-25 10:34:0020周年集字徽章-年
日期:2023-04-23 11:17:52
7 [报告]
发表于 2014-05-28 17:44 |只看该作者
本帖最后由 bikkuri 于 2014-05-28 17:57 编辑

谢谢damcool大侠!
我也找出来了我的程序的错误,主要是在对`字符的处理上错了。
很高兴抛砖引玉能引出您的高大上程序!收藏学习了!

论坛徽章:
145
技术图书徽章
日期:2013-10-01 15:32:13戌狗
日期:2013-10-25 13:31:35金牛座
日期:2013-11-04 16:22:07子鼠
日期:2013-11-18 18:48:57白羊座
日期:2013-11-29 10:09:11狮子座
日期:2013-12-12 09:57:42白羊座
日期:2013-12-24 16:24:46辰龙
日期:2014-01-08 15:26:12技术图书徽章
日期:2014-01-17 13:24:40巳蛇
日期:2014-02-18 14:32:59未羊
日期:2014-02-20 14:12:13白羊座
日期:2014-02-26 12:06:59
8 [报告]
发表于 2014-09-05 10:07 |只看该作者
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP