2013-03-07 91 views
2

我自动化RSA软令牌转换并将转换字符串传递给Outlook。我意识到我不能使用批处理命令行将字符串转换为URL,但这不是我的问题。我的问题是将讨厌的等号转换为它的URL编码等价物“%3D”。具有延迟变量扩展的批处理文件 - URL编码 - 等号 - RSA令牌转换器

@echo off 
setlocal enableDelayedExpansion 

set /p fname=Enter the Filename: 
set /p pss=Enter the encryption pass: 

IF NOT EXIST "%fname%".sdtid (
echo File Not Found! Closing... 
PING 1.1.1.1 -n 4 >NUL 
exit 
) 

echo File Found! starting process... 

REM tokenconverter %fname%.sdtid -iphone >> temp_batch.txt 
tokenconverter %fname%.sdtid -p %pss% -iphone >> temp_batch.txt 

set /p result= < temp_batch.txt 
DEL temp_batch.txt 
REM %result% | clip 

set "stringclean1=!result:?=%%3F!" 
set "stringclean2=!stringclean1::=%%3A!" 
set "stringclean3=!stringclean2:/=%%2F!" 

下面一行未能编码等号:但是等号仍然未编码

set "stringclean4=!stringclean3:=^=%%3D!" 
set "stringclean4=!stringclean3:=%=%%3D!" 

set "stringclean4=!stringclean3:==%%3D!" 

我试过。

echo Piping over to outlook.. 
REM passing stringclean3 since stringclean4 no worky. 
pushd "C:\Program Files\Microsoft Office\Office12" 
outlook.exe /c ipm.note /m "&subject=TEsT&body=%stringclean3%" 

使用延迟变量扩展对等号进行URL编码的正确方法是什么?

任何帮助表示赞赏。提前致谢。

回答

3

对不起,分批更换=一个简单的解决方案,根本不存在:-(

关于您可以使用纯批量做的最好的是遍历字符串,字符为单位,并根据需要更换。

这里是有一定的空间,更优化的蛮力解决方案,但它是不够好。它首先检查是否抽空编码=之前存在=

:: test if string contains = 
:: only take the time to encode = if it exists 
set "test=a!stringClean3!" 
for /f "delims=" %%S in ("!test!") do if /i "!test:%%S=%%S!" neq "!test!" (

    :: compute length of string - 1 
    set end=0 
    for /l %%A in (12,-1,0) do (
    set /a "end|=1<<%%A" 
    for %%B in (!end!) do if "!stringClean3:~%%B,1!"=="" set /a "end&=~1<<%%A" 
) 

    :: replace = with %3D 
    for /l %%N in (0 1 !end!) do (
    if "!stringClean3:~%%N,1!" equ "=" (
     set "stringClean4=!stringClean4!%%3D" 
    ) else (
     set "stringClean4=!stringClean4!!stringClean3:~%%N,1!" 
    ) 
) 

) else set stringClean4=!stringClean3! 


编辑

这是另一种完全不同的方法,它使用CERTUTIL将字符串编码和解码为十六进制。编码十六进制字符串很简单。我不认为CERTUTIL是随XP提供的。我不记得了,但CERTUTIL语法可能会稍微改变,这取决于Windows的版本。我在Vista上开发并测试了它。

set "tempFile=%temp%\replaceEqual%random%" 

(>"%tempFile%.before" echo(!stringClean3!) 
certutil -encodehex "%tempFile%.before" "%tempFile%.hex" >nul 
>"%tempFile%.hex2" (
    for /f "usebackq tokens=1*" %%A in ("%tempFile%.hex") do (
    set ln=%%B 
    set "ln=!ln:~0,48!" 
    (echo !ln:3d=25 33 44!) 
) 
) 
certutil -decodehex "%tempFile%.hex2" "%tempFile%.after" >nul 
<"%tempFile%.after" set /p "stringClean4=" 
del "%tempFile%.*" 

使用SET/P的读取结果导致了以下的限制:

  • 字符串必须小于或等于1021个字符。
  • 字符串不能以控制字符结束(后控制字符被剥离)
  • 的字符串不能包含换行符

结果可能使用FOR/F被读取,但随后的延迟扩展当FOR变量被扩展时将会破坏任何!

+0

+1有效的,但我敢肯定,这将是一个批处理+的JScript/VBScript的混合解决方案一个良好的事业。正则表达式替换可能比字符逐字检查和替换更有效。你知道你想。 :) – rojo 2013-03-07 03:02:05

+0

@rojo - 是的,我几乎扔了那个解决方案。但更好的是使用encodeURIComponent()来处理编码的所有方面的JScript解决方案(可能是混合JScript/Batch)。 – dbenham 2013-03-07 03:11:35

0
SET result=qm?colon:slash/equal=qm?colon:slash/equal=end 
set "stringclean0=!result!" 
:loop3D 
FOR /f "tokens=1,2*delims==" %%i IN ('SET stringclean0') DO (
    IF NOT "%%k"=="" set stringclean0=%%j%%3D%%k&GOTO loop3D 
) 
set "stringclean1=!stringclean0:?=%%3F!" 
set "stringclean2=!stringclean1::=%%3A!" 
set "stringclean3=!stringclean2:/=%%2F!" 

SET stri 
+0

如果连续存在'=',则此算法失败,并且问题无法修复。如果'stringclean0X'存在,它也失败,但是这个问题可以解决。 – dbenham 2013-03-07 05:48:33

3

dbenham对使用JScript的encodeURIComponent方法有个好主意。这就是塞到OP的示例脚本:

@echo off 
setlocal 

set /p fname=Enter the Filename: 
set /p pss=Enter the encryption pass: 

IF NOT EXIST "%fname%".sdtid (
    echo File Not Found! Closing... 
    PING 1.1.1.1 -n 4 >NUL 
    exit 
) 

echo File Found! starting process... 

echo WScript.Stdout.WriteLine(encodeURIComponent(WScript.StdIn.ReadLine()));>uri.js 
for /f "delims=" %%I in (
    'tokenconverter %fname%.sdtid -p %pss% -iphone ^| cscript /nologo uri.js' 
) do set "result=%%I" 
del uri.js 
+0

不错,但是你应该禁用延迟扩展,至少在'set'result = %%之前,我会'''否则你会失去感叹号和插入符 – jeb 2013-03-07 13:36:29

+0

好主意。无论如何,脚本中没有任何需要'enabledelayedexpansion'的东西,所以现在它已经消失了。 – rojo 2013-03-07 13:42:55