|
3742668
荣誉版主
积分 2013
发帖 718
注册 2006-2-18
状态 离线
|
『楼 主』:
Re pengfei 关于特殊字符的问题
由于消息系统似乎出了故障,回了你两次消息似乎都没有成功,现开一贴回复你的消息,3天后删除。
Quote: | 你好, 突然想到一种新的加密方案, 写了代码, 初步能实现简单的批处理加密.
昨天把特殊字符的问题解决了, 突然发现批处理中定义的环境变量加密后出错了(%号的问题).
上论坛找找资料, 就在加密的贴子中发现版主对这种加密方案已经有一定研究了(环境变量截取字符加密). 批处理中只是不牵涉到环境变量或%号的问题一般都能加密. 现在头疼, 希望版主能想到更好的办法. |
|
对于处理文本中的特殊字符,个人认为最有效的方法就是把字符变量化。举两个例子你可以参考参考:
@echo off
setlocal ENABLEDELAYEDEXPANSION
set "a=&%!|_)|+"
set b=a
echo !%b%!
for /f "delims=" %%i in ("%a%") do echo %%i
echo %a%
pause 上面就是两个字符变量化的例子,本来准备打算专门就特殊字符处理发个贴的,不过由于时间关系一直没有写,希望你有空能写个出来吧。
虽然利用字符变量化可以处理任何特殊字符,但是得到的却是更复杂的结构,更难组织的代码。所以,在实际应用中,处理字符的工作我都是用vbs来完成,效果要比批处理好得多。
|
|
2006-11-20 12:51 |
|
|
3742668
荣誉版主
积分 2013
发帖 718
注册 2006-2-18
状态 离线
|
『第
2 楼』:
现在时刻,凌晨1点整,睡觉去了。
更正一下,由于上线的随机性,此贴于下次上线时删除。
|
|
2006-11-20 14:01 |
|
|
namejm
荣誉版主
batch fan
积分 5226
发帖 1737
注册 2006-3-10 来自 成都
状态 离线
|
『第
3 楼』:
建议 3742668 兄不用删这个帖子,把帖子改造一下,就可以成为讨论CMD特殊字符的专题帖子了,要不然,刚发不久就删除的话,只有有限的几个人可以看到,那就太遗憾了。
|
尺有所短,寸有所长,学好CMD没商量。
考虑问题复杂化,解决问题简洁化。 |
|
2006-11-21 02:40 |
|
|
pengfei
银牌会员
积分 1218
发帖 485
注册 2006-7-21 来自 湖南.娄底
状态 离线
|
『第
4 楼』:
非常感谢3742668版主的耐心解答, 变量加密中的环境变量代码转换我已经解决了, 谢谢你!
版主讲的字符变量化的方法可以把特殊字符显示出来, 我也对特殊字符的处理及批处理变量的处理机制有一点点自己的看法.
批处理以DOS程序为基础, 变量的定义使用非常方便, 并且批处理对变量的处理机制也很特殊. 它的变量值都可以当作命令成分执行, 我想这种机制除了批处理其他程序设计或脚本语言中都不会有. 举个例子:
@echo off
set "a=>"
echo dos i love you%a%dos.txt
pause 上面的代码证实, 把管道命令">"赋给a值, echo dos i love you%a%dos.txt在这一句代码中出现变量%a%, 当执行到这个语句时实际dos命令为(echo dos i love you>dos.txt), 这里他并不是会回显这个重定向符号, 而是当作命令把dos i love you重定向至dos.txt中. 系统自动在执行echo语句前从内存中找到变量a的值, 和释放到内存的整个echo语句一起当作命令执行了
这就是批处理的变量处理机制, 当执行语句前把语句中的变量先用变量值替换, 再执行, 这种处理机制有利也有弊, 它提高了批处理脚本的灵活性. 同时也会造成很多麻烦, 就像这个问题, 还有复合语句中变量的更新. 微软显然考虑到了这点, 它可以延迟环境变量扩充. 在执行语句前不先替换变量的值, 而是在语句执行后再根据变量取出相应的值, 把变量值当作数据处理.
要显示特殊字符, 我们就需要延缓环境变量扩充, 把这些字符不作为命令部分执行. 而是当做语句中的数据来处理.
@echo off
setlocal enabledelayedexpansion
set "a=>"
echo dos i love you!a!dos.txt
pause 上面的代码完整的显示echo dos i love you>dos.txt, 而没有重定向至dos.txt. 就是延缓变量扩充的结果, 它在echo命令执行到!a!时才把重定向符号从内存取出来显示, 并不是在命令执行前用变量值替换变量的位置.
@echo off
setlocal enabledelayedexpansion
set "a=&%!^|()|><+-"/*""
echo !a!
pause 3742668版主一楼的代码显示特殊字符也是利用延迟环境变量扩充, 不知道我这种说法是不是对的.
如果不用环境变量延迟扩充, 我们还可以利用控制字符的优先级来解决, 我们用引号来做个试验.
@echo off
set "a=&%!^|()|><+-"/*""
echo "%a%"
pause 或者
@echo off
set "a=&%!^|()|><+-"/*""
set /p "ii=%a%"<nul
pause 上面的代码说明引号可以将这些特殊字符当作需要加工的数据来处理, 而不是语句中的执行部分. 虽然没有开启延缓环境变量扩充, 但是这些特殊字符依然可以正常显示.
我对批处理也没有更深的理解, 不知如何解释. 目前我只好把他和C语言中的括号运算符来做比较. 引号的优先级高于这些一般的控制字符, 比如上面的管道命令符. 用引号括起来后系统把他们当作一般的字符处理了. 当语句执行到引号开始时, 系统认为引号内的部分是语句需要处理的数据, echo "%a%"这里=&%!^|()|><+-"/*"都会正常显示出来. 引号优化于&><等命令, 在echo命令执行时引号先于管道命令把特殊字符当做echo语句需要处理的数据执行.
我对这种机制也是似懂非懂, 还请3742668版主和高手们有更加准确说明.
[ Last edited by pengfei on 2006-12-4 at 03:54 AM ]
|
业精于勤而荒于嬉,形成于思而毁于随。 |
|
2006-11-21 11:52 |
|
|
lxmxn
版主
积分 11386
发帖 4938
注册 2006-7-23
状态 离线
|
『第
5 楼』:
Quote: | CODE: [Copy to clipboard]
--------------------------------------------------------------------------------
@echo off
setlocal enabledelayedexpansion
set "a=&%!^|()|><+-"/*""
echo !a!
pause
3742668版主一楼的代码显示特殊字符也是利用延迟环境变量扩充, 不知道我这种说法是不是对的. |
|
原封不动的拷贝到bat文件,执行结果并不是我想象的那样:&%!^|()|><+-"/*",而是:
&|()|><+-"/*"
|
|
2006-11-21 13:39 |
|
|
lxmxn
版主
积分 11386
发帖 4938
注册 2006-7-23
状态 离线
|
『第
6 楼』:
经过测试,pengfei 兄所列的后三个例子中,并没有完好的把"%"百分号给显示出来,貌似这个百分号(%)比双引号(")的优先级更大哦。
p.s. 建议版主不要把这个帖子给删除了,这是个很好的讨论帖子,值得学习。
[ Last edited by lxmxn on 2006-11-22 at 01:55 AM ]
|
|
2006-11-21 13:46 |
|
|
pengfei
银牌会员
积分 1218
发帖 485
注册 2006-7-21 来自 湖南.娄底
状态 离线
|
『第
7 楼』:
Re: lxmxn
这个%号在批处理中有特殊的含义, 它应该是转义, 可以代表环境变量%str%..., 可替换变量%a, %I...等, 也可以是参数%1, %2... 出现%号并不会显示这个符号, 而是将其后面的字符转义成以上的变量或参数等.
要显示%号批处理中以双百分号来显示.
@echo off
set "a=&%%!^|()|><+-"/*""
set /p "ii=%a%"<nul
pause 上面的代码用两个%号, 显示一个%号出来.
@echo off
set "a=&% %!^|()|><+-"/*""
set /p "ii=%a%"<nul
pause 而上面的代码将两个百分号用空格间隔, 又没有显示了, 这是系统把这两个百分号中间的空格当作变量, 当然这个变量在内存中没有任何值. 因此也没有显示.
@echo off
set "a=&%!^|()|><%+-"/*""
set /p "ii=%a%"<nul
pause 这里两个百分号之间的!^|()|><这些字符都当做环境变量处理了, 并不会显示出来. 一个百分号系统将其当作参数等处理, 两个百分号当环境变量处理. 这是批处理的处理机制.
[ Last edited by pengfei on 2006-11-22 at 01:00 AM ]
|
业精于勤而荒于嬉,形成于思而毁于随。 |
|
2006-11-22 00:24 |
|
|
lxmxn
版主
积分 11386
发帖 4938
注册 2006-7-23
状态 离线
|
『第
8 楼』:
RE: pengfei
那兄在4楼举的几个例子是为了说明什么呢?
[ Last edited by lxmxn on 2006-11-22 at 01:55 AM ]
|
|
2006-11-22 01:09 |
|
|
pengfei
银牌会员
积分 1218
发帖 485
注册 2006-7-21 来自 湖南.娄底
状态 离线
|
『第
9 楼』:
Re: lxmxn兄
那几个例子是说明批处理对环境变量的处理机制(特殊字符的处理), 也不知道对不对. 个人理解而已.
|
业精于勤而荒于嬉,形成于思而毁于随。 |
|
2006-11-22 01:15 |
|
|
vkill
金牌会员
积分 4103
发帖 1744
注册 2006-1-20 来自 甘肃.临泽
状态 离线
|
『第
10 楼』:
我更喜欢用"
set "a=&|()|><+-"/*%%""
call :abc "%a%"
:abc
echo "%~1"
|
|
2006-11-22 01:23 |
|
|
lxmxn
版主
积分 11386
发帖 4938
注册 2006-7-23
状态 离线
|
『第
11 楼』:
突然发现我把 pengfei 兄的ID给打错了,连忙改了过来,不好意思哈。
关于对%的显示,无论怎么样,都要%%来转义,偶个人觉得还是不够完美。
对于 pengfei 兄的:
Quote: | 而上面的代码将两个百分号用空格间隔, 又没有显示了, 这是系统把这两个百分号中间的空格当作变量, 当然这个变量在内存中没有任何值. |
|
我觉得这个空格应该不能当作变量,无论怎么赋值给空格,怎么也不成功。大家可以测试一下。既然赋值不成功,它也就不能叫变量了吧。?
|
|
2006-11-22 02:00 |
|
|
pengfei
银牌会员
积分 1218
发帖 485
注册 2006-7-21 来自 湖南.娄底
状态 离线
|
『第
12 楼』:
赋值给空格当然不符合set命令的用法了.
但% %这里两个百分号系统是当作环境变量处理的, 并不是说它是一个实际存在的变量. 当系统把% %当作变量在内存中取值时当然找不到了, 变量未定义.
[ Last edited by pengfei on 2006-11-24 at 02:18 AM ]
|
业精于勤而荒于嬉,形成于思而毁于随。 |
|
2006-11-22 02:06 |
|
|
不得不爱
超级版主
我爱DOS
积分 5310
发帖 2044
注册 2005-9-26 来自 四川南充
状态 离线
|
|
2006-11-22 03:11 |
|
|
hxuan999
中级用户
DOS之日
积分 337
发帖 161
注册 2006-11-4
状态 离线
|
『第
14 楼』:
Quote: | ` @ # $ ^ & ( ) - _ + \ | ] [ } { ' ; : ? / > < , . " |
|
这些都是可以做变量的字符,比如:
set ":=111"
echo "%:%"
结果就是111了.
另外空格是可以在变量名是出现的,只要不是第一个字符就OK.比如.%a a%和%a a %,都可以做变量名,但是不是同一变量.
此帖被 +4 点积分 点击查看详情 评分人:【 lxmxn 】 | 分数: +1 | 时间:2006-11-24 01:36 | 评分人:【 redtek 】 | 分数: +1 | 时间:2006-11-24 07:41 | 评分人:【 220110 】 | 分数: +2 | 时间:2006-11-24 13:25 |
|
|
for /f %%h in (`echo hxuan`) do for /f %%x in (`echo hxuan`) do if %%h==%%x nul |
|
2006-11-24 00:57 |
|
|
lxmxn
版主
积分 11386
发帖 4938
注册 2006-7-23
状态 离线
|
『第
15 楼』:
经过测试,果然可行,为楼上加分。
|
|
2006-11-24 01:38 |
|