samcarter
> This is part of the Summer of Code 2022 series, see https://topanswers.xyz/tex?q=2059 for more information
Decode the following text, which was encoded using a [Caesar cipher ](https://en.wikipedia.org/wiki/Caesar_cipher)
> Lopybo nkgx dro exnobnemuvsxq gyuo. Ro nsnx’d rkfo dro poovsxq yp losxq govv bocdon. Led xyxodrovocc ro uxog drkd drsc gkc dro nki ro cryevn vokfo. Ohmozd ckisxq qyynlio dy rsc lovyfon yxoc drobo gkc xydrsxq ryvnsxq rsw lkmu. Rsc nemu rkn coxd rsw yx dro wycd swzybdkxd wsccsyx k psfo goouc yvn sxohzobsoxmon exnobnemuvsxq gkc ofob coxd yx. Ro lsn pkbogovv dy rsc wydrob, kvv rsc lbydrobc kxn cscdobc, kxn psxkvvi pbyw rsc nemu. Dro lkq gkc cryevnobon, dro lyydc gobo dson, dro exnobnemuvsxq vopd.
---
Giving credit to the author is a bit hard without spoiling the fun, so here also in code
> Itmi ipztc ugdb iwt qgxaaxpci sjrzjbtcih eprzpvt qn @Hzxaabdc
![SoC.png](/image?hash=55c244608cebcbdce01dcae8a284309ef818ae750847f79f3606cac694fa7292)
Top Answer
frougon
\* This line is not a spoiler. \*
Because of the space tokens, I used a similar technique as in [Soc day 2](https://topanswers.xyz/tex?q=2079#a2316), with the notable addition of `\__socxii_apply_shift:nn`. My code works even with 8-bit engines and the nasty RIGHT SINGLE QUOTATION MARK (U+2019) that was left in the message (!).
The code outputs the 25 non-trivial shifted results; one has to choose the correct one “by eye”.
```
\documentclass{article}
\ExplSyntaxOn
% #1: shift amount to apply
% #2: an explicit character token
\cs_new:Npn \__socxii_apply_shift:nn #1#2
{
\bool_case_true:nF
{
{ % uppercase letters
\bool_lazy_and_p:nn
{ ! \int_compare_p:nNn { `#2~ } < { 65 } }
{ \int_compare_p:nNn { `#2~ } < { 91 } }
}
{
\char_generate:nn { 65 + \int_mod:nn { `#2~ + #1 - 65 } { 26 } } { 11 }
}
{ % lowercase letters
\bool_lazy_and_p:nn
{ ! \int_compare_p:nNn { `#2~ } < { 97 } }
{ \int_compare_p:nNn { `#2~ } < { 123 } }
}
{
\char_generate:nn { 97 + \int_mod:nn { `#2~ + #1 - 97 } { 26 } } { 11 }
}
}
{ % Other non-space character tokens: passthrough.
% The \exp_not:n is for multibyte UTF-8 sequences on non-Unicode
% engines when inputenc is not very recent (with recent inputenc,
% these chars are \protected so the \exp_not:n wouldn't be needed).
\exp_not:n {#2}
}
}
\cs_generate_variant:Nn \__socxii_apply_shift:nn { ne }
\use:n { \cs_new:Npn \__socxii_gobble_space:w } ~ { }
% #1: shift amount to apply
% #2: message made of explicit character tokens
\cs_new:Npn \__socxii_shift_message:nn #1#2
{
\tl_if_head_is_space:nTF {#2}
{ ~ \__socxii_shift_message:no {#1} { \__socxii_gobble_space:w #2 } }
{
\tl_if_empty:nF {#2}
{
\__socxii_apply_shift:ne {#1} { \tl_head:n {#2} }
\__socxii_shift_message:ne {#1} { \tl_tail:n {#2} }
}
}
}
\cs_generate_variant:Nn \__socxii_shift_message:nn { no, ne }
\cs_new_protected:Npn \socxii_caesar_try_all_shifts:n #1
{
\int_step_inline:nn { 25 } % 0 or 26 a priori not useful!
{
\par
% Multibyte UTF-8 sequences must be kept as is (the first char of such
% a sequence is active and expects the second one to immediately
% follow, not \__socxii_shift_message:ne).
\use:x { \__socxii_shift_message:nn {##1} {#1} }
\par
}
}
\cs_new_eq:NN \caesarTryAllShifts \socxii_caesar_try_all_shifts:n
\ExplSyntaxOff
\begin{document}
\section{The message}
\caesarTryAllShifts{%
Lopybo nkgx dro exnobnemuvsxq gyuo. Ro nsnx’d rkfo dro poovsxq yp losxq govv
bocdon. Led xyxodrovocc ro uxog drkd drsc gkc dro nki ro cryevn vokfo. Ohmozd
ckisxq qyynlio dy rsc lovyfon yxoc drobo gkc xydrsxq ryvnsxq rsw lkmu. Rsc
nemu rkn coxd rsw yx dro wycd swzybdkxd wsccsyx k psfo goouc yvn sxohzobsoxmon
exnobnemuvsxq gkc ofob coxd yx. Ro lsn pkbogovv dy rsc wydrob, kvv rsc
lbydrobc kxn cscdobc, kxn psxkvvi pbyw rsc nemu. Dro lkq gkc cryevnobon, dro
lyydc gobo dson, dro exnobnemuvsxq vopd.%
}
\section{The author}
\caesarTryAllShifts{%
Itmi ipztc ugdb iwt qgxaaxpci sjrzjbtcih eprzpvt qn @Hzxaabdc%
}
\end{document}
```
Cleartext message:
![image.png](/image?hash=22cc95f646489b3f674edbfff5535af6fb1495534e5f2e9085031c318082b9b1)
Attribution:
![image.png](/image?hash=cf593d0d2d53cda27b3c4d8a960d8ff102edff4c6fcad1c3f5291ca99d359d7e)