具有延迟变量扩展的批处理文件 - URL编码 - 等号 - RSA令牌转换器

时间:2013-03-07 00:31:20

标签: batch-file cmd rsa url-encoding delayedvariableexpansion

我正在自动执行RSA软令牌转换并将转换字符串传递给Outlook。我意识到我无法使用批处理到Outlook命令行将字符串转换为URL,但这不是我的问题。我的问题是将讨厌的等号转换为它的URL编码等效符号“%3D”。

@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 个答案:

答案 0 :(得分: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变量展开时,延迟扩展将损坏任何!

答案 1 :(得分: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

答案 2 :(得分: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