Пакетный файл с отложенным расширением переменной - кодировка URL - знак равенства - RSA Token Converter
Я автоматизирую преобразование программного токена RSA и передаю строку преобразования в Outlook. Я понимаю, что не могу превратить строку в URL, используя пакетную командную строку для outlook, однако это не моя проблема. Моя проблема заключается в преобразовании надоедливого знака равенства в его кодированный в 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 ответа
У 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
Простите, простое решение для замены =
в партии просто не существует:-(
Самое лучшее, что вы можете сделать, используя чистый пакет, - это циклически проходить строку, символ за символом и заменять при необходимости.
Вот решение грубой силы, в котором есть место для большей оптимизации. Но это достаточно хорошо. Сначала проверяется, =
существует, прежде чем найти время для кодирования =
,
:: 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 раскрывается.
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