This should allow all ASCII printable characters.
\begin{filecontents*}{plain.txt}
u&9@@^{=!{{}
Karl's students do not care about dashing patterns.
Karl's students do not care about arrow tips.
Karl's students, by the way, do not know what a transformation matrix is.
\end{filecontents*}
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\int_gzero_new:N \g_karl_offset_int
\ior_new:N \l_karl_input_stream
\iow_new:N \l_karl_output_stream
\seq_new:N \l__karl_input_seq
\tl_new:N \l__karl_input_tl
\tl_new:N \l__karl_temp_tl
\tl_const:Nn \c_karl_space_tl { ~ }
\NewDocumentCommand{\cypher}{omm}
{% #1 = shift #2 = input file, #3 = output file
\IfValueT{#1}{ \int_gset:Nn \g_karl_offset_int { #1 } }
\ior_open:Nn \l_karl_input_stream { #2 }
\iow_open:Nn \l_karl_output_stream { #3 }
\ior_str_map_inline:Nn \l_karl_input_stream
{
\tl_set:Nn \l__karl_input_tl { ##1 }
\tl_replace_all:Nnn \l__karl_input_tl { ~ } { \c_karl_space_tl }
\karl_write:V \l__karl_input_tl
}
\ior_close:N \l_karl_input_stream
\iow_close:N \l_karl_output_stream
}
\cs_new_protected:Npn \karl_write:n #1
{
\tl_clear:N \l__karl_temp_tl
\tl_map_inline:nn { #1 } { \karl_shift:n { ##1 } }
\iow_now:NV \l_karl_output_stream \l__karl_temp_tl
}
\cs_generate_variant:Nn \karl_write:n { V }
\cs_generate_variant:Nn \iow_now:Nn { NV }
\cs_new_protected:Npn \karl_shift:n #1
{
\group_begin:
\token_if_eq_meaning:NNTF #1 \c_karl_space_tl
{
\char_set_lccode:nn { `~ } { \g_karl_offset_int + 32 }
\tl_to_lowercase:n { \group_end: \tl_put_right:Nn \l__karl_temp_tl { ~ } }
}
{
\int_compare:nTF { `#1 + \g_karl_offset_int > 126 }
{ \char_set_lccode:nn { `#1 } { `#1 + \g_karl_offset_int - 126 + 32 } }
{
\int_compare:nTF { `#1 + \g_karl_offset_int < 32 }
{ \char_set_lccode:nn { `#1 } { `#1 + \g_karl_offset_int + 126 - 32 } }
{ \char_set_lccode:nn { `#1 } { `#1 + \g_karl_offset_int } }
}
\tl_to_lowercase:n { \group_end: \tl_put_right:Nn \l__karl_temp_tl { #1 } }
}
}
\ExplSyntaxOff
\cypher[13]{plain.txt}{thirteen.txt}
\cypher[-13]{thirteen.txt}{plain13.txt}
\cypher[15]{plain.txt}{fifteen.txt}
\cypher[-15]{fifteen.txt}{plain15.txt}
\stop
plain.txt
u&9@@^{=!{{}
Karl's students do not care about dashing patterns.
Karl's students do not care about arrow tips.
Karl's students, by the way, do not know what a transformation matrix is.
thirteen.txt
$3FMMk*J.**,
Xn!y4"-"#$qr{#"-q|-{|#-pn!r-no|$#-qn"uv{t-}n##r!{";
Xn!y4"-"#$qr{#"-q|-{|#-pn!r-no|$#-n!!|&-#v}";
Xn!y4"-"#$qr{#"9-o(-#ur-&n(9-q|-{|#-x{|&-&un#-n-#!n{"s|!zn#v|{-zn#!v'-v";
plain13.txt
u&9@@^{=!{{}
Karl's students do not care about dashing patterns.
Karl's students do not care about arrow tips.
Karl's students, by the way, do not know what a transformation matrix is.
fifteen.txt
&5HOOm,L0,,.
Zp#{6$/$%&st}%$/s~/}~%/rp#t/pq~&%/sp$wx}v/!p%%t#}$=
Zp#{6$/$%&st}%$/s~/}~%/rp#t/pq~&%/p##~(/%x!$=
Zp#{6$/$%&st}%$;/q*/%wt/(p*;/s~/}~%/z}~(/(wp%/p/%#p}$u~#|p%x~}/|p%#x)/x$=
plain15.txt
u&9@@^{=!{{}
Karl's students do not care about dashing patterns.
Karl's students do not care about arrow tips.
Karl's students, by the way, do not know what a transformation matrix is.
#1the sequence\char\numexpr`#1+\offset\relaxcan give you the offset letter (I have defined\offsetas a count). Problems I encountered: Spaces, text encoding, braces in the output (decoding fails for all special characters), writing out. – Qrrbrbirlbel Mar 21 '13 at 01:00TeXquestion? There are programming languages (awk,python,perl...) better suited for filters that read from a file, do something, and write the result to a file. – Ethan Bolker Mar 21 '13 at 01:13