LaTeX 中的 Base64 编码?

LaTeX 中的 Base64 编码?

我们如何使用 LaTeX 中的 Base64 编码对某些文本/字符串进行编码?或者还有其他解决方案吗?

例如字符串的Base64编码LatexbGF0ZXg=

以下是我想要做的事情的描述:

\newcommand{\String}{LATEX}
\newcommand{\BaseEncode}{**something** \String **something**}

答案1

LuaTeX 附带了 LuaSocket,其MIME 模块支持多种常见的编码和解码。

所有代码块都是一个文件:

\documentclass{article}
\usepackage{luacode}
\begin{luacode*}
local mime = require("mime")
local lft = lua.get_functions_table()
lft[#lft + 1] = function()
    local str = token.scan_string()
    tex.sprint(-2, (mime.b64(str)))
end
token.set_lua("BaseEncode", #lft, "global")
lft[#lft + 1] = function()
    local str = token.scan_string()
    tex.sprint(-2, (mime.unb64(str)))
end
token.set_lua("BaseDecode", #lft, "global")
\end{luacode*}
\begin{document}
\texttt{\BaseEncode{Hello, world!}}

\BaseDecode{SGVsbG8sIHdvcmxkIQ==}
\end{document}

答案2

有趣的编程任务!:)

这是 base64 编码和解码代码。编码时,它\int_to_bin:n在每个字符上使用 填充到 8 位,然后将输出分成 6 位块,并使用查找宏来选择编码字符。解码时,它进行查找以将编码输入标准化为 ASCII,然后然后在每个字符上使用\int_to_bin:n,填充至 6 位,然后将其分成 8 位块并用来\char_generate:nn制作 ASCII 字符。

下面的代码打印了 的 base64 编码Hello, world!,然后打印了 的 base64 解码:

在此处输入图片描述

这些命令是可扩展的,因此您可以轻松地使用它们写入文件或终端

\documentclass{article}

\ExplSyntaxOn
\NewExpandableDocumentCommand \BaseEncode { m }
  { \zeeshan_base_encode:n {#1} }
\NewExpandableDocumentCommand \BaseDecode { m }
  { \zeeshan_base_decode:n {#1} }
\cs_new:Npn \zeeshan_base_encode:n #1
  {
    \exp_args:Ne \__zeeshan_base_encode_bin:n
      { \str_map_function:nN {#1} \__zeeshan_base_char_to_bin:n }
  }
\cs_new:Npn \__zeeshan_base_char_to_bin:n #1
  { \exp_args:Nf \__zeeshan_base_char_to_bin_pad:nn { \int_to_bin:n { `#1 } } { 8 } }
\cs_new:Npn \__zeeshan_base_char_to_bin_pad:nn #1 #2
  { \prg_replicate:nn { #2 - \str_count:n {#1} } { 0 } #1 }
\cs_new:Npn \__zeeshan_base_encode_bin:n #1
  { \__zeeshan_base_encode_bin:w #1 222222 \q_stop }
\cs_new:Npn \__zeeshan_base_encode_bin:w #1#2#3#4#5#6
  { \__zeeshan_base_encode_bin_aux:w #1#2#3#4#5#6 2 \q_nil }
\cs_new:Npn \__zeeshan_base_encode_bin_aux:w #1 2 #2 \q_nil
  {
    \tl_if_empty:nTF {#2}
      { \exp_args:Nf \__zeeshan_base_encode_lookup:n { \int_from_bin:n {#1} } }
      {
        \tl_if_empty:nT {#1} { \use_none_delimit_by_q_stop:w }
        \exp_args:Nf \__zeeshan_base_encode_lookup:n
          {
            \exp_args:Ne \int_from_bin:n
              { #1 \prg_replicate:nn { \str_count:n {#2} } { 0 } }
          }
        \int_compare:nNnTF { \str_count:n {#2} } = { 2 } { = } { == }
        \use_none_delimit_by_q_stop:w
      }
    \__zeeshan_base_encode_bin:w
  }
\cs_new:Npn \__zeeshan_base_encode_lookup:n #1
  {
    \if_int_compare:w #1 < 26 ~
      \char_generate:nn { #1 + `A } { 12 }
    \else:
      \if_int_compare:w #1 < 52 ~
        \char_generate:nn { #1 + `a - 26 } { 12 }
      \else:
        \if_int_compare:w #1 < 62 ~
          \char_generate:nn { #1 + `0 - 52 } { 12 }
        \else:
          \if_int_compare:w #1 = 62 ~ + \else: / \fi:
        \fi:
      \fi:
    \fi:
  }
%
\cs_new:Npn \zeeshan_base_decode:n #1
  {
    \exp_args:Ne \__zeeshan_base_decode_bin:n
      { \str_map_function:nN {#1} \__zeeshan_base_to_bin:n }
  }
\cs_new:Npn \__zeeshan_base_to_bin:n #1
  {
    \exp_args:Ne \__zeeshan_base_char_to_bin_pad:nn
      { \__zeeshan_base_to_bin_lookup:n {#1} } { 6 }
  }
\cs_new:Npn \__zeeshan_base_to_bin_lookup:n #1
  {
    \if_int_compare:w `#1 > 47 ~
      \if_int_compare:w `#1 > 64 ~
        \int_to_bin:n { `#1 - \if_int_compare:w `#1 > 96 ~ 71 \else: 65 \fi: }
      \else:
        \if_int_compare:w `#1 = 61 ~ 222222
        \else: \int_to_bin:n { `#1 + 4 }
        \fi:
      \fi:
    \else: 11111 \if_int_compare:w `#1 = 43 ~ 0 \else: 1 \fi:
    \fi:
  }
\cs_new:Npn \__zeeshan_base_decode_bin:n #1
  { \__zeeshan_base_decode_bin:w #1 2222 2222 \q_stop }
\cs_new:Npn \__zeeshan_base_decode_bin:w #1#2#3#4#5#6#7#8
  { \__zeeshan_base_decode_bin_aux:w #1#2#3#4#5#6#7#8 2 \q_nil }
\cs_new:Npn \__zeeshan_base_decode_bin_aux:w #1 2 #2 \q_nil
  {
    \tl_if_empty:nTF {#2}
      { \exp_args:Nf \__zeeshan_base_output_decoded:n { \int_from_bin:n {#1} } }
      { \use_none_delimit_by_q_stop:w }
    \__zeeshan_base_decode_bin:w
  }
\cs_new:Npn \__zeeshan_base_output_decoded:n #1
  { \int_compare:nNnTF {#1} = { 32 } { ~ } { \char_generate:nn {#1} { 12 } } }
\ExplSyntaxOff

\begin{document}

\texttt{\BaseEncode{Hello, world!}}

\BaseDecode{SGVsbG8sIHdvcmxkIQ==}

\edef\x{\BaseEncode{Hello, world!}}
\typeout{Encoded: \x}

\typeout{Decoded: \expandafter\BaseDecode\expandafter{\x}}

\end{document}

答案3

如果您已-shell-escape启用,则这是一个相当简单的解决方案(请注意,启用-shell-escape会打开各种安全问题,因此请谨慎操作)。\BaseEncode\BaseDecode命令可以将返回字符串保存在可选参数中,如第三个示例所示。如果您使用的是 Windows,则只需将的定义更改\base@sixtyfour@cmd为任何可用的 base64 编码/解码命令行工具。

\documentclass{article}
\makeatletter
\newcommand\BaseEncode[2][\relax]{\expandafter\base@sixtyfour\detokenize{#2}$E#1}
\newcommand\BaseDecode[2][\relax]{\expandafter\base@sixtyfour\detokenize{#2}$D#1}
\def\base@sixtyfour#1$#2#3{%
  \begingroup
    \endlinechar\m@ne \everyeof{\noexpand}%
    \ifx \relax#3\@@input"|\base@sixtyfour@cmd{#1}{#2}" \relax
    \else\xdef#3{\@@input"|\base@sixtyfour@cmd{#1}{#2}" }%
    \fi
  \endgroup}
\def\base@sixtyfour@cmd#1#2{echo #1 | base64 \ifx D#2--decode \fi -}
\makeatother
\begin{document}
\texttt{\BaseEncode{Hello, world!}}

\BaseDecode{SGVsbG8sIHdvcmxkIQo=}

\BaseEncode[\tmp]{Hello, world!}
\typeout{Encoded: \tmp}
\end{document}

相关内容