batch-file - Xor bat 文件中的字符串?

标签 batch-file

简而言之,我想给我的 friend 一个执行以下操作的 bat 文件(未经测试)

echo Your mother is so fat
pause
echo the recursive function computing her mass causes a stack overflow

我可能会复制/粘贴他的 bat 文件,所以我不希望妙语被破坏。如何隐藏文本?我想我可以将字符串存储在一个变量中,在我回显之前,我应该对每个字母与 32 进行异或。但我不知道如何取一个字符串,对每个字母进行异或而不是回显以显示笑话。我该如何隐藏文本?我也可以对它进行 BASE64 编码/解码,但如果我只使用 bat 文件,IDK 如何做到这一点

最佳答案

这是我内心深处的一个主题,因为我在 my implementation of the classic Colossal Cave Adventure game as a Windows batch file. 中做了类似的事情。

在游戏脚本中,我有选择地加密显示文本、变量名称和注释。解码加密文本的代码直接嵌入在同一个脚本中!我正常写游戏的源码,用大括号表示要加密的部分。游戏中的一个功能可以生成自己的加密形式!

我使用了一个简单的对称旋转密码,所以实际上它比加密更令人困惑。但这就是游戏和你的情况所需要的。

我已经提取了例程的简化版本并在下面提供了它们。

第一个脚本是一个独立的脚本,它有选择地加密源文件中的文本并将结果写入标准输出。只需将输出重定向到新文件即可获得文件的加密版本。

选择性ROT13.bat

@echo off
:selectiveROT13  InFile
::
::  Selectively applies the simple "rotate alphabet 13 places" cipher
::  to the contents of file InFile. Only text between curly braces
::  is affected. The affected content can span multiple lines.
::
::  Writes the results to stdout.
::  Percent completion is continuously written to stderr.
::
setlocal enableDelayedExpansion
set "upper=ABCDEFGHIJKLMNOPQRSTUVWXYZ"
set "lower=abcdefghijklmnopqrstuvwxyz"
for /l %%A in (0 1 25) do (
  set /a "B=(%%A+13)%%26"
  for /f %%B in ("!B!") do (
    set "upper!upper:~%%A,1!=!upper:~%%B,1!"
    set "lower!lower:~%%A,1!=!lower:~%%B,1!"
  )
)
setlocal disableDelayedExpansion
>&2 cls
set "active="
for /f %%N in ('type %1^|find /c /v ""') do set /a "lnCnt=%%N, pct=-1"
for /f "skip=2 tokens=1,* delims=[]" %%a in ('find /v /n "" %1') do (
  set "ln=%%b"
  setlocal enableDelayedExpansion
  set "str=A!ln!"
  set "len=0"
  for /L %%A in (12,-1,0) do (
    set /a "len|=1<<%%A"
    for %%B in (!len!) do if "!str:~%%B,1!"=="" set /a "len&=~1<<%%A"
  )
  set /a len-=1
  set rtn=
  for /l %%n in (0,1,!len!) do (
    set "c=!ln:~%%n,1!"
    if "!c!" equ "{" set "active=1"
    if "!c!" equ "}" set "active="
    if defined active if defined upper!c! for /f %%c in ("!c!") do (
      if "!upper:%%c=%%c!" equ "!upper!" (
        set "c=!upper%%c!"
      ) else (
        set "c=!lower%%c!"
      )
    )
    set "rtn=!rtn!!c!"
  )
  echo(!rtn!
  for %%A in ("!active!") do (
    endlocal
    set "active=%%~A"
  )
)
exit /b 0

下面是您的笑话程序,其中包含用于解码加密文本的代码的简化版本。我的原始代码适用于字符串变量,但此版本适用于字符串文字。源脚本正常编写,没有加密。大括号指示要加密的代码。除了你的笑话,我还提供了文档和示例来演示一些功能。

joke_src.bat
@echo off
setlocal enableDelayedExpansion
call :init

:: Disable delayed expansion to protect ! within string literals
setlocal disableDelayedExpansion

:: Curly braces are used to denote text that should be encrypted.
:: Encryption can span multiple lines
:: {
:::Line1
:::Line2
:::Line3
:: }

:: I defined a simple SHOW macro that expands to CALL :SHOW
:: Use the %show% macro to display encrypted text.
:: The braces can be hidden by using the undefined %{% & %}% variables
%show% %{%"Quote literals ("") must be doubled ("""") in the source"%}%

:: Here I use a FOR loop to show all encrypted lines within this script
:: that begin with :::
echo(
for /f "delims=: tokens=*" %%A in ('findstr /b ":::" "%~f0"') do %show% "%%A"

echo(
echo And now it is time for a little joke.
echo(
echo Your mother is so fat...
pause
%show% %{%"the recursive function computing her mass causes a stack overflow!"%}%
exit /b


:show  Str
::{
::  Applies the simple "rotate alphabet 13 places" cipher to string Str
::  and writes the result to stdout. Consecutive quotes ("") are converted
::  into a single quote (").
::}
  setlocal disableDelayedExpansion
  set "str=%~1"
  setlocal enableDelayedExpansion
  set "str=!str:""="!^"
  if defined {obfuscated} (
    set "len=0"
    set "str2=.!str!"
    for /L %%A in (12,-1,0) do (
      set /a "len|=1<<%%A"
      for %%B in (!len!) do if "!str2:~%%B,1!"=="" set /a "len&=~1<<%%A"
    )
    set /a len-=1
    set rtn=
    for /l %%n in (0,1,!len!) do (
      set "c=!str:~%%n,1!"
      if defined {upper}!c! for /f %%c in ("!c!") do (
        if "!{upper}:%%c=%%c!" equ "!{upper}!" (
          set "c=!{upper}%%c!"
        ) else (
          set "c=!{lower}%%c!"
        )
      )
      set "rtn=!rtn!!c!"
    )
  ) else set "rtn=!str!"
  echo(!rtn!
exit /b 0


:init
  set "}="
  set "{="}
  set "{upper}=ABCDEFGHIJKLMNOPQRSTUVWXYZ"
  set "{lower}=abcdefghijklmnopqrstuvwxyz"
  for /l %%A in (0 1 25) do (
    set /a "B=(%%A+13)%%26"
    for /f %%B in ("!B!") do (
      set "{upper}!{upper}:~%%A,1!=!{upper}:~%%B,1!"
      set "{lower}!{lower}:~%%A,1!=!{lower}:~%%B,1!"
    )
  )
  set "{obfuscated}="
  set "{obfuscationTest}={A}"
  if "!{obfuscationTest}:A=!" equ "!{obfuscationTest}!" set {obfuscated}=1
  set "show=call :show"
exit /b

以下命令将生成脚本的加密版本:
selectiveROT13 joke_src.bat >joke.bat

下面是加密形式。这是您要发送给您的 friend 的内容。 (当然没有额外的文档和示例)

笑话.bat
@echo off
setlocal enableDelayedExpansion
call :init

:: Disable delayed expansion to protect ! within string literals
setlocal disableDelayedExpansion

:: Curly braces are used to denote text that should be encrypted.
:: Encryption can span multiple lines
:: {
:::Yvar1
:::Yvar2
:::Yvar3
:: }

:: I defined a simple SHOW macro that expands to CALL :SHOW
:: Use the %show% macro to display encrypted text.
:: The braces can be hidden by using the undefined %{% & %}% variables
%show% %{%"Dhbgr yvgrenyf ("") zhfg or qbhoyrq ("""") va gur fbhepr"%}%

:: Here I use a FOR loop to show all encrypted lines within this script
:: that begin with :::
echo(
for /f "delims=: tokens=*" %%A in ('findstr /b ":::" "%~f0"') do %show% "%%A"

echo(
echo And now it is time for a little joke.
echo(
echo Your mother is so fat...
pause
%show% %{%"gur erphefvir shapgvba pbzchgvat ure znff pnhfrf n fgnpx biresybj!"%}%
exit /b


:show  Str
::{
::  Nccyvrf gur fvzcyr "ebgngr nycunorg 13 cynprf" pvcure gb fgevat Fge
::  naq jevgrf gur erfhyg gb fgqbhg. Pbafrphgvir dhbgrf ("") ner pbairegrq
::  vagb n fvatyr dhbgr (").
::}
  setlocal disableDelayedExpansion
  set "str=%~1"
  setlocal enableDelayedExpansion
  set "str=!str:""="!^"
  if defined {boshfpngrq} (
    set "len=0"
    set "str2=.!str!"
    for /L %%A in (12,-1,0) do (
      set /a "len|=1<<%%A"
      for %%B in (!len!) do if "!str2:~%%B,1!"=="" set /a "len&=~1<<%%A"
    )
    set /a len-=1
    set rtn=
    for /l %%n in (0,1,!len!) do (
      set "c=!str:~%%n,1!"
      if defined {hccre}!c! for /f %%c in ("!c!") do (
        if "!{hccre}:%%c=%%c!" equ "!{hccre}!" (
          set "c=!{hccre}%%c!"
        ) else (
          set "c=!{ybjre}%%c!"
        )
      )
      set "rtn=!rtn!!c!"
    )
  ) else set "rtn=!str!"
  echo(!rtn!
exit /b 0


:init
  set "}="
  set "{="}
  set "{hccre}=ABCDEFGHIJKLMNOPQRSTUVWXYZ"
  set "{ybjre}=abcdefghijklmnopqrstuvwxyz"
  for /l %%A in (0 1 25) do (
    set /a "B=(%%A+13)%%26"
    for /f %%B in ("!B!") do (
      set "{hccre}!{hccre}:~%%A,1!=!{hccre}:~%%B,1!"
      set "{ybjre}!{ybjre}:~%%A,1!=!{ybjre}:~%%B,1!"
    )
  )
  set "{boshfpngrq}="
  set "{boshfpngvbaGrfg}={N}"
  if "!{boshfpngvbaGrfg}:A=!" equ "!{boshfpngvbaGrfg}!" set {boshfpngrq}=1
  set "show=call :show"
exit /b

这个系统的美妙之处在于 joke.bat 和 joke_src.bat 生成完全相同的输出:
Quote literals (") must be doubled ("") in the source

Line1
Line2
Line3

And now it is time for a little joke.

Your mother is so fat...
Press any key to continue . . .
the recursive function computing her mass causes a stack overflow!

另一个不错的功能是selectiveROT13.bat 可以应用于joke.bat 以重新生成原始未加密的源。

关于batch-file - Xor bat 文件中的字符串?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25582295/

相关文章:

windows - 如何根据前缀列表(txt)批量复制文件

batch-file - 清除MSMQ队列并从bat文件重置IIS

windows - DOSKEY 召回别名

windows - 如果 Windows .BAT 文件中不存在文件,如何删除快捷方式?

batch-file - 在子文件夹中查找文件夹并获取文件夹路径的批处理脚本

batch-file - 用于提取变量部分的批处理命令

batch-file - 读取批处理文件中参数的每个字符

git - "' git ' is not recognized as an internal"blah blah 即使命令第一次运行

windows - 批处理脚本中的问题读取用户输入

powershell - 如何在win10命令提示符下使用ffmpeg连接来自不同子目录的视频文件?