Just in time processing on a character stream: Difference between revisions

m
→‎{{header|11l}}: new way of specifying file open mode
(+Racket)
m (→‎{{header|11l}}: new way of specifying file open mode)
 
(15 intermediate revisions by 7 users not shown)
Line 1:
{{draft task}}
Given a stream of characters, presumablycontaining (simulated)the fromseparator a keyboard, that contain the separatorscharacters "formfeed", "linefeed", "tab" and "space", characters. Printprint out the i<sup>th</sup> character of the i<sup>th</sup> tab-field of the i<sup>th</sup> line of the i<sup>th</sup> page to reveal a secret password.
 
Stop processing immediately upon encountering a "!" found uniquely in this <i>i,i,i,i</i> position (leastlest the system self -destruct). The "!" may be found/permitted else whereelsewhere however, in which case it should be ignored.
 
Ideally this can be generalisegeneralised as follows:
* The separatorsseparator (formfeed,characters linefeed,are tab,defined space) provided fromby a user -supplied array andthat can include additional/ or alternative separators, e.g. (formfeed, linefeed, ".", "," ," ",...).
* TheseThe selection criterialcriterion is generalised i<sup>th</sup>,i<sup>th</sup>,i<sup>th</sup>,i<sup>th</sup> to a boolean function of <i>f(page,line,field,word,...) <b>or</b> f(i<sup>th</sup>,j<sup>th</sup>,k<sup>th</sup>,l<sup>th</sup>,m<sup>th</sup>,etc...)</i>
 
Provide a reasonably interesting message to be decoded, e.g. "Silence-Dogood". Your choice.
 
This task was inspired by the movie "[[wp:National_Treasure_%28film%29|National Treasure]]", withwhich refers to a "[[wp:Book cipher|book cipher]]".
 
=={{header|11l}}==
{{trans|Python}}
 
<syntaxhighlight lang="11l">T UserInput
Int formFeed
Int lineFeed
Int tab
Int space
 
F (chunk)
.formFeed = chunk[0]
.lineFeed = chunk[1]
.tab = chunk[2]
.space = chunk[3]
 
F String()
R ‘(ff=#.; lf=#.; tb=#.; sp#.)’.format(.formFeed, .lineFeed, .tab, .space)
 
F chunks(l, n)
[[Int]] r
L(i) (0 .< l.len).step(n)
r.append(l[i .+ n])
R r
 
F getUserInput()
V h = ‘0 18 0 0 0 68 0 1 0 100 0 32 0 114 0 45 0 38 0 26 0 16 0 21 0 17 0 59 0 11 ’""
‘0 29 0 102 0 0 0 10 0 50 0 39 0 42 0 33 0 50 0 46 0 54 0 76 0 47 0 84 2 28’
V ha = h.split(‘ ’).map(Int)
R chunks(ha, 4).map(chunk -> UserInput(chunk))
 
F decode(filename, uiList)
V f = File(filename)
V text = f.read()
 
F decode2(ui)
V f = 0
V l = 0
V t = 0
V s = 0
L(c) @text
I f == ui.formFeed & l == ui.lineFeed & t == ui.tab & s == ui.space
I c == ‘!’
R 0B
print(c, end' ‘’)
R 1B
I c.code == 0'C
f = f + 1
l = 0
t = 0
s = 0
E I c == "\n"
l = l + 1
t = 0
s = 0
E I c == "\t"
t = t + 1
s = 0
E
s = s + 1
R 0B
 
L(ui) uiList
I !decode2(ui)
L.break
print()
 
V uiList = getUserInput()
decode(‘theRaven.txt’, uiList)</syntaxhighlight>
 
{{out}}
<pre>
Silence-Dogood.
</pre>
 
=={{header|C}}==
{{trans|C++}}
<langsyntaxhighlight lang="c">#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
Line 229 ⟶ 303:
 
return 0;
}</langsyntaxhighlight>
{{out}}
<pre>Silence-Dogood.</pre>
 
=={{header|C++ sharp|C#}}==
Text used to encode:[http://paulo-jorente.de/text/theRaven.txt The Raven - by E.A.Poe]
<lang cpp>
#include <vector>
#include <iostream>
#include <fstream>
#include <sstream>
 
typedef struct {
int s[4];
}userI;
 
class jit{
public:
void decode( std::string& file, std::vector<userI>& ui ) {
std::ifstream f( file.c_str(), std::ios_base::in );
fileBuffer = std::string( ( std::istreambuf_iterator<char>( f ) ), std::istreambuf_iterator<char>() );
f.close();
for( std::vector<userI>::iterator t = ui.begin(); t != ui.end(); t++ ) {
if( !decode( ( *t ).s ) ) break;
}
std::cout << "\n\n";
}
private:
bool decode( int* ui ) {
int l = 0, t = 0, p = 0, c = 0, a = 0;
for( std::string::iterator i = fileBuffer.begin(); i != fileBuffer.end(); i++ ) {
if( p == ui[0] && l == ui[1] && t == ui[2] && c == ui[3] ) {
if( *i == '!' ) return false;
std::cout << *i; return true;
}
if( *i == '\n' ) { l++; t = c = 0; }
else if( *i == '\t' ) { t++; c = 0; }
else if( *i == '\f' ) { p++; l = t = c = 0; }
else { c++;}
}
return false;
}
std::string fileBuffer;
};
void getUserInput( std::vector<userI>& u ) {
std::string h = "0 18 0 0 0 68 0 1 0 100 0 32 0 114 0 45 0 38 0 26 0 16 0 21 0 17 0 59 0 11 "
"0 29 0 102 0 0 0 10 0 50 0 39 0 42 0 33 0 50 0 46 0 54 0 76 0 47 0 84 2 28";
//std::getline( std::cin, h );
std::stringstream ss( h );
userI a;
int x = 0;
while( std::getline( ss, h, ' ' ) ) {
a.s[x] = atoi( h.c_str() );
if( ++x == 4 ) {
u.push_back( a );
x = 0;
}
}
}
int main( int argc, char* argv[] ) {
std::vector<userI> ui;
getUserInput( ui );
 
jit j;
j.decode( std::string( "theRaven.txt" ), ui );
return 0;
}
</lang>
{{out}}
<pre>
Silence-Dogood.
</pre>
 
=={{header|C#|C sharp}}==
{{trans|D}}
<langsyntaxhighlight lang="csharp">using System;
using System.Collections.Generic;
using System.Linq;
Line 382 ⟶ 387:
}
}
}</langsyntaxhighlight>
{{out}}
<pre>Silence-Dogood.</pre>
 
=={{header|C++}}==
Text used to encode:[http://paulo-jorente.de/text/theRaven.txt The Raven - by E.A.Poe]
<syntaxhighlight lang="cpp">
#include <vector>
#include <iostream>
#include <fstream>
#include <sstream>
 
typedef struct {
int s[4];
}userI;
 
class jit{
public:
void decode( std::string& file, std::vector<userI>& ui ) {
std::ifstream f( file.c_str(), std::ios_base::in );
fileBuffer = std::string( ( std::istreambuf_iterator<char>( f ) ), std::istreambuf_iterator<char>() );
f.close();
for( std::vector<userI>::iterator t = ui.begin(); t != ui.end(); t++ ) {
if( !decode( ( *t ).s ) ) break;
}
std::cout << "\n\n";
}
private:
bool decode( int* ui ) {
int l = 0, t = 0, p = 0, c = 0, a = 0;
for( std::string::iterator i = fileBuffer.begin(); i != fileBuffer.end(); i++ ) {
if( p == ui[0] && l == ui[1] && t == ui[2] && c == ui[3] ) {
if( *i == '!' ) return false;
std::cout << *i; return true;
}
if( *i == '\n' ) { l++; t = c = 0; }
else if( *i == '\t' ) { t++; c = 0; }
else if( *i == '\f' ) { p++; l = t = c = 0; }
else { c++;}
}
return false;
}
std::string fileBuffer;
};
void getUserInput( std::vector<userI>& u ) {
std::string h = "0 18 0 0 0 68 0 1 0 100 0 32 0 114 0 45 0 38 0 26 0 16 0 21 0 17 0 59 0 11 "
"0 29 0 102 0 0 0 10 0 50 0 39 0 42 0 33 0 50 0 46 0 54 0 76 0 47 0 84 2 28";
//std::getline( std::cin, h );
std::stringstream ss( h );
userI a;
int x = 0;
while( std::getline( ss, h, ' ' ) ) {
a.s[x] = atoi( h.c_str() );
if( ++x == 4 ) {
u.push_back( a );
x = 0;
}
}
}
int main( int argc, char* argv[] ) {
std::vector<userI> ui;
getUserInput( ui );
 
jit j;
j.decode( std::string( "theRaven.txt" ), ui );
return 0;
}
</syntaxhighlight>
{{out}}
<pre>
Silence-Dogood.
</pre>
 
=={{header|D}}==
{{trans|Kotlin}}
<langsyntaxhighlight Dlang="d">import std.algorithm;
import std.array;
import std.conv;
Line 452 ⟶ 526:
auto uiList = getUserInput();
decode("theRaven.txt", uiList);
}</langsyntaxhighlight>
{{out}}
<pre>Silence-Dogood.</pre>
Line 458 ⟶ 532:
=={{header|Go}}==
{{trans|C++}}
<langsyntaxhighlight lang="go">package main
 
import (
Line 536 ⟶ 610:
log.Fatal(err)
}
}</langsyntaxhighlight>
 
{{out}}
Line 545 ⟶ 619:
=={{header|Java}}==
{{trans|Kotlin}}
<langsyntaxhighlight lang="java">import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
Line 663 ⟶ 737:
decode("theRaven.txt", uiList);
}
}</langsyntaxhighlight>
{{out}}
<pre>Silence-Dogood.</pre>
 
=={{header|jq}}==
'''Adapted from [[#Wren|Wren]]'''
{{works with|jq}}
'''Works with gojq, the Go implementation of jq'''
<syntaxhighlight lang="jq"># User input takes the form of quadtuples of integers: [formFeed, lineFeed, tab, space]
def getUserInput:
def nwise($n):
def n: if length <= $n then . else .[0:$n] , (.[$n:] | n) end;
n;
 
"0 18 0 0 0 68 0 1 0 100 0 32 0 114 0 45 0 38 0 26 0 16 0 21 0 17 0 59 0 11 " +
"0 29 0 102 0 0 0 10 0 50 0 39 0 42 0 33 0 50 0 46 0 54 0 76 0 47 0 84 2 28"
| split(" ") | map(tonumber) | nwise(4)
| {formFeed: .[0], lineFeed: .[1], tab: .[2], space: .[3]} ;
 
def emit_until(cond; stream):
label $out | stream | if cond then break $out else . end;
 
# Input should be the text as a (long) string
def decode($uiList):
def stream: explode[] | [.] | implode;
def decode2(ui):
. as $text
| label $out
| foreach stream as $c (
{ f: 0, l: 0, t: 0, s: 0 };
if .f == ui.formFeed and .l == ui.lineFeed and .t == ui.tab and .s == ui.space
then .out = $c
elif $c == "\f"
then .f += 1
| .l = 0
| .t = 0
| .s = 0
elif $c == "\n"
then .l += 1
| .t = 0
| .s = 0
elif $c == "\t"
then .t += 1
| .s = 0
else .s += 1
end;
if .out then .out, break $out else empty end )
// "" ;
decode2($uiList) ;
 
# Input: the text
[emit_until(. == "!"; getUserInput as $ui | decode($ui)) ] | add</syntaxhighlight>
{{out}}
Invocation: jq -Rsr -f program.jq theRaven.txt
<pre>
Silence-Dogood.
</pre>
 
=={{header|Julia}}==
Customization is via adding to or deleting from the chars dictionary.
<langsyntaxhighlight lang="julia">@enum streamstate GET_FF GET_LF GET_TAB GET_CHAR ABORT
chars = Dict(GET_FF => ['\f'], GET_LF => ['\n'], GET_TAB => ['\t'])
 
Line 708 ⟶ 836:
 
stream_decode_jit(open("filename.txt", "r"))
</syntaxhighlight>
</lang>
 
=={{header|Kotlin}}==
{{trans|C++}}
<langsyntaxhighlight lang="scala">// version 1.2.10
 
import java.io.File
Line 761 ⟶ 889:
val uiList = getUserInput()
decode("theRaven.txt", uiList)
}</langsyntaxhighlight>
 
{{out}}
Line 767 ⟶ 895:
Silence-Dogood.
</pre>
 
=={{header|Nim}}==
{{trans|Kotlin}}
With some modifications compared to the model.
 
<syntaxhighlight lang="nim">import options, sequtils, strutils
 
type Position = tuple[ff, lf, tab, sp: int]
 
func buildUserInput(s: string): seq[Position] =
let valList = s.splitWhitespace().map(parseInt)
doAssert valList.len mod 4 == 0, "Number of values must be a multiple of four."
doAssert valList.allIt(it >= 0), "Expected non negative values."
let posList = valList.distribute(valList.len div 4)
result = posList.mapIt((ff: it[0], lf: it[1], tab: it[2], sp: it[3]))
 
 
proc decode(filename: string; uiList: seq[Position]): string =
 
func decode(text: string; ui: Position): Option[char] =
var f, l, t, s = 0
let (ff, lf, tab, sp) = ui
for c in text:
if f == ff and l == lf and t == tab and s == sp:
return if c == '!': none(char) else: some(c)
case c
of '\f': inc f; l = 0; t = 0; s = 0
of '\l': inc l; t = 0; s = 0
of '\t': inc t; s = 0
else: inc s
 
let text = filename.readFile()
for ui in uiList:
let c = text.decode(ui)
if c.isNone: break
result.add c.get()
 
const UiList = buildUserInput("0 18 0 0 0 68 0 1 0 100 0 32 0 114 0 " &
"45 0 38 0 26 0 16 0 21 0 17 0 59 0 11 " &
"0 29 0 102 0 0 0 10 0 50 0 39 0 42 0 " &
"33 0 50 0 46 0 54 0 76 0 47 0 84 2 28")
 
echo "theRaven.txt".decode(UiList)</syntaxhighlight>
 
{{out}}
<pre>Silence-Dogood.</pre>
 
=={{header|Perl}}==
{{trans|Perl 6Raku}}
{{libheader|ntheory}}
<langsyntaxhighlight lang="perl">use strict;
use warnings;
use feature 'say';
Line 824 ⟶ 998:
 
my $enc = jit_encode('The slithey toves did gyre and gimble in the wabe');
say my $result = "Encoded\n$enc\n\nDecoded\n" . jit_decode($enc);</langsyntaxhighlight>
{{out}}
<pre>Encoded
Line 831 ⟶ 1,005:
Decoded
The slithey toves did gyre and gimble in the wabe</pre>
 
=={{header|Perl 6}}==
{{works with|Rakudo|2019.03}}
 
This is a something of a toy encoder / decoder and probably shouldn't be used for anything serious.
 
Default encode/decode key is 'Perl 6' Feed it a pass phrase at the command line to use that instead.
 
Will handle any visible character in the ASCII range as well as space and new-line.
 
<lang perl6>#`[
Set srand to set the encode / decode "key".
Need to use the same "key" and same implementation
of Perl 6 to encode / decode. Gain "security" by
exchanging "keys" by a second channel. Default
"key" is "Perl 6"
]
 
unit sub MAIN ($key = 'Perl 6');
 
srand $key.comb(/<.alnum>/).join.parse-base(36) % 2**63;
 
my @stream = (flat "\n", ' ' .. '~').roll(*);
 
sub jit-encode (Str $str) {
my $i = 0;
my $last = 0;
my $enc = '';
for $str.comb -> $c {
my $h;
my $l = '';
++$i until $i > 1 && $c eq @stream[$i];
my $o = $i - $last;
$l = $o % 26;
$h = $o - $l if $o >= 26;
$l += 10;
$enc ~= ($h ?? $h.base(36).uc !! '') ~ ($l.base(36).lc);
$last = $i;
}
my $block = 60;
$enc.comb($block).join: "\n"
}
 
sub jit-decode (Str $str is copy) {
$str.=subst("\n", '', :g);
$str ~~ m:g/((.*?) (<:Ll>))/;
my $dec = '';
my $i = 0;
for $/.List -> $l {
my $o = ($l[0][1].Str.parse-base(36) - 10 // 0) +
($l[0][0].Str.parse-base(36) // 0);
$i += $o;
$dec ~= @stream[$i];
}
$dec
}
 
my $secret = q:to/END/;
In my opinion, this task is pretty silly.
 
'Twas brillig, and the slithy toves
Did gyre and gimble in the wabe.
 
!@#$%^&*()_+}{[].,><\|/?'";:1234567890
END
 
say "== Secret: ==\n$secret";
 
say "\n== Encoded: ==";
say my $enc = jit-encode($secret);
 
say "\n== Decoded: ==";
say jit-decode($enc);</lang>
 
<pre>== Secret: ==
In my opinion, this task is pretty silly.
 
'Twas brillig, and the slithy toves
Did gyre and gimble in the wabe.
 
!@#$%^&*()_+}{[].,><\|/?'";:1234567890
 
 
== Encoded: ==
26j52d6Ie1Ge4Cd26po1GdsQa3Ms52piQd4Cn3Md2Wcf1GtciQz1GwQb5Si2
WnQlQmQjQv1GmQra2Wt4Cpc1Gysatu26va1Gq52x4Cp1Gv4CeQv1Gb1Gp4Co
6IbaQyAUmd26a7Yw3Mh2Wu26v1GfQsQwbQpn26z1Gi1Gl1GmQb1Gfs26v4Ce
Qy2Wm78xaaa4Cj26x6If3Msqu2Wx2Wku1Gh52ydQh3Mb78rll1GvcQap5Sgy
Qm26s1Gh26clj1Gm1GzA4y26bat1Gdk1Gs1Gpm1GlQs7Ys52dQw1Giv5Se5S
u3Mb1Gucn4Cq26h26pQq2Wh5Sh7Yi8OrpQl26p26i3MqtQiQhQi4Ckb3Mi
 
== Decoded: ==
In my opinion, this task is pretty silly.
 
'Twas brillig, and the slithy toves
Did gyre and gimble in the wabe.
 
!@#$%^&*()_+}{[].,><\|/?'";:1234567890</pre>
 
=={{header|Phix}}==
{{trans|C}}
{{libheader|Phix/libcurl}}
<lang Phix>-- demo/rosetta/BookCipher.exw
<!--<syntaxhighlight lang="phix">(notonline)-->
function decode(integer fn, sequence ui)
<span style="color: #000080;font-style:italic;">-- demo/rosetta/BookCipher.exw</span>
integer {ff,lf,tab,sp} = ui,
<span style="color: #008080;">function</span> <span style="color: #000000;">decode</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">fn</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">sequence</span> <span style="color: #000000;">ui</span><span style="color: #0000FF;">)</span>
f = 0, l = 0, t = 0, s = 0
<span style="color: #004080;">integer</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">ff</span><span style="color: #0000FF;">,</span><span style="color: #000000;">lf</span><span style="color: #0000FF;">,</span><span style="color: #000000;">tab</span><span style="color: #0000FF;">,</span><span style="color: #000000;">sp</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">ui</span><span style="color: #0000FF;">,</span>
while true do
<span style="color: #000000;">f</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">l</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">t</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">s</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
integer c = getc(fn)
<span style="color: #008080;">while</span> <span style="color: #004600;">true</span> <span style="color: #008080;">do</span>
if c=-1 then return false end if
<span style="color: #004080;">integer</span> <span style="color: #000000;">c</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">getc</span><span style="color: #0000FF;">(</span><span style="color: #000000;">fn</span><span style="color: #0000FF;">)</span>
if f==ff and l==lf and t==tab and s==sp then
<span style="color: #008080;">if</span> <span style="color: #000000;">c</span><span style="color: #0000FF;">=-</span><span style="color: #000000;">1</span> <span style="color: #008080;">then</span> <span style="color: #008080;">return</span> <span style="color: #004600;">false</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
if c=='!' then return false end if
<span style="color: #008080;">if</span> <span style="color: #000000;">f</span><span style="color: #0000FF;">==</span><span style="color: #000000;">ff</span> <span style="color: #008080;">and</span> <span style="color: #000000;">l</span><span style="color: #0000FF;">==</span><span style="color: #000000;">lf</span> <span style="color: #008080;">and</span> <span style="color: #000000;">t</span><span style="color: #0000FF;">==</span><span style="color: #000000;">tab</span> <span style="color: #008080;">and</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">==</span><span style="color: #000000;">sp</span> <span style="color: #008080;">then</span>
puts(1,c)
<span style="color: #008080;">if</span> <span style="color: #000000;">c</span><span style="color: #0000FF;">==</span><span style="color: #008000;">'!'</span> <span style="color: #008080;">then</span> <span style="color: #008080;">return</span> <span style="color: #004600;">false</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
return true
<span style="color: #7060A8;">puts</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">c</span><span style="color: #0000FF;">)</span>
elsif c==#0C then
<span style="color: #008080;">return</span> <span style="color: #004600;">true</span>
f += 1
<span style="color: #008080;">elsif</span> <span style="color: #000000;">c</span><span style="color: #0000FF;">==</span><span style="color: #000000;">#0C</span> <span style="color: #008080;">then</span>
{l, t, s} @= 0
<span style="color: #000000;">f</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
elsif c=='\n' then
<span style="color: #0000FF;">{</span><span style="color: #000000;">l</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">t</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">}</span>
l += 1
<span style="color: #008080;">elsif</span> <span style="color: #000000;">c</span><span style="color: #0000FF;">==</span><span style="color: #008000;">'\n'</span> <span style="color: #008080;">then</span>
{t, s} @= 0
<span style="color: #000000;">l</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
elsif c=='\t' then
<span style="color: #0000FF;">{</span><span style="color: #000000;">t</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">}</span>
t += 1
<span style="color: #008080;">elsif</span> <span style="color: #000000;">c</span><span style="color: #0000FF;">==</span><span style="color: #008000;">'\t'</span> <span style="color: #008080;">then</span>
s = 0
<span style="color: #000000;">t</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
else
<span style="color: #000000;">s</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
s += 1
<span style="color: #008080;">else</span>
end if
<span style="color: #000000;">s</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
end while
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
return false
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
end function
<span style="color: #008080;">return</span> <span style="color: #004600;">false</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
include builtins\libcurl.e
 
<span style="color: #008080;">include</span> <span style="color: #000000;">builtins</span><span style="color: #0000FF;">\</span><span style="color: #000000;">libcurl</span><span style="color: #0000FF;">.</span><span style="color: #000000;">e</span>
procedure decodeFile(string filename, url, sequence code)
if not file_exists(filename) then
<span style="color: #008080;">procedure</span> <span style="color: #000000;">decodeFile</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">filename</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">url</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">sequence</span> <span style="color: #000000;">code</span><span style="color: #0000FF;">)</span>
printf(1,"Downloading %s...\n",{filename})
<span style="color: #008080;">if</span> <span style="color: #008080;">not</span> <span style="color: #7060A8;">file_exists</span><span style="color: #0000FF;">(</span><span style="color: #000000;">filename</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span>
CURLcode res = curl_easy_get_file(url,"",filename) -- (no proxy)
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"Downloading %s...\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">filename</span><span style="color: #0000FF;">})</span>
if res!=CURLE_OK then
<span style="color: #004080;">CURLcode</span> <span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">curl_easy_get_file</span><span style="color: #0000FF;">(</span><span style="color: #000000;">url</span><span style="color: #0000FF;">,</span><span style="color: #008000;">""</span><span style="color: #0000FF;">,</span><span style="color: #000000;">filename</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- (no proxy)</span>
string error = sprintf("%d",res)
<span style="color: #008080;">if</span> <span style="color: #000000;">res</span><span style="color: #0000FF;">!=</span><span style="color: #004600;">CURLE_OK</span> <span style="color: #008080;">then</span>
if res=CURLE_COULDNT_RESOLVE_HOST then
<span style="color: #004080;">string</span> <span style="color: #000000;">error</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">sprintf</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"%d"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">res</span><span style="color: #0000FF;">)</span>
error &= " [CURLE_COULDNT_RESOLVE_HOST]"
<span style="color: #008080;">if</span> <span style="color: #000000;">res</span><span style="color: #0000FF;">=</span><span style="color: #000000;">CURLE_COULDNT_RESOLVE_HOST</span> <span style="color: #008080;">then</span>
end if
<span style="color: #000000;">error</span> <span style="color: #0000FF;">&=</span> <span style="color: #008000;">" [CURLE_COULDNT_RESOLVE_HOST]"</span>
crash("Error %s downloading file\n", {error})
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
end if
<span style="color: #7060A8;">crash</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"Error %s downloading file\n"</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">error</span><span style="color: #0000FF;">})</span>
end if
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
integer fn = open(filename, "r")
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
if fn=-1 then crash("could not open %s",{filename}) end if
<span style="color: #004080;">integer</span> <span style="color: #000000;">fn</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">open</span><span style="color: #0000FF;">(</span><span style="color: #000000;">filename</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"r"</span><span style="color: #0000FF;">)</span>
for i=1 to length(code) do
<span style="color: #008080;">if</span> <span style="color: #000000;">fn</span><span style="color: #0000FF;">=-</span><span style="color: #000000;">1</span> <span style="color: #008080;">then</span> <span style="color: #7060A8;">crash</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"could not open %s"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">filename</span><span style="color: #0000FF;">})</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
if not decode(fn,code[i]) then exit end if
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">code</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
if seek(fn, 0)!=SEEK_OK then crash("seek error") end if
<span style="color: #008080;">if</span> <span style="color: #008080;">not</span> <span style="color: #000000;">decode</span><span style="color: #0000FF;">(</span><span style="color: #000000;">fn</span><span style="color: #0000FF;">,</span><span style="color: #000000;">code</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">])</span> <span style="color: #008080;">then</span> <span style="color: #008080;">exit</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
end for
<span style="color: #008080;">if</span> <span style="color: #7060A8;">seek</span><span style="color: #0000FF;">(</span><span style="color: #000000;">fn</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">)!=</span><span style="color: #004600;">SEEK_OK</span> <span style="color: #008080;">then</span> <span style="color: #7060A8;">crash</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"seek error"</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
printf(1,"\n\n");
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
end procedure
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"\n\n"</span><span style="color: #0000FF;">);</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
constant code = {{0,18,0,0},
{0,68,0,1},
<span style="color: #008080;">constant</span> <span style="color: #000000;">code</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{{</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">18</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">},</span>
{0,100,0,32},
<span style="color: #0000FF;">{</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">68</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">},</span>
{0,114,0,45},
<span style="color: #0000FF;">{</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">100</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">32</span><span style="color: #0000FF;">},</span>
{0,38,0,26},
<span style="color: #0000FF;">{</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">114</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">45</span><span style="color: #0000FF;">},</span>
{0,16,0,21},
<span style="color: #0000FF;">{</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">38</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">26</span><span style="color: #0000FF;">},</span>
{0,17,0,59},
<span style="color: #0000FF;">{</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">16</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">21</span><span style="color: #0000FF;">},</span>
{0,11,0,29},
<span style="color: #0000FF;">{</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">17</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">59</span><span style="color: #0000FF;">},</span>
{0,102,0,0},
<span style="color: #0000FF;">{</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">11</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">29</span><span style="color: #0000FF;">},</span>
{0,10,0,50},
<span style="color: #0000FF;">{</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">102</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">},</span>
{0,39,0,42},
<span style="color: #0000FF;">{</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">10</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">50</span><span style="color: #0000FF;">},</span>
{0,33,0,50},
<span style="color: #0000FF;">{</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">39</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">42</span><span style="color: #0000FF;">},</span>
{0,46,0,54},
<span style="color: #0000FF;">{</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">33</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">50</span><span style="color: #0000FF;">},</span>
{0,76,0,47},
<span style="color: #0000FF;">{</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">46</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">54</span><span style="color: #0000FF;">},</span>
{0,84,2,28}}
<span style="color: #0000FF;">{</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">76</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">47</span><span style="color: #0000FF;">},</span>
decodeFile("theRaven.txt", "http://paulo-jorente.de/text/theRaven.txt", code)
<span style="color: #0000FF;">{</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">84</span><span style="color: #0000FF;">,</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">28</span><span style="color: #0000FF;">}}</span>
{} = wait_key()</lang>
<span style="color: #000000;">decodeFile</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"theRaven.txt"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"http://paulo-jorente.de/text/theRaven.txt"</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">code</span><span style="color: #0000FF;">)</span>
<span style="color: #0000FF;">{}</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">wait_key</span><span style="color: #0000FF;">()</span>
<!--</syntaxhighlight>-->
{{out}}
<pre>
Line 1,006 ⟶ 1,085:
=={{header|Python}}==
{{trans|D}}
<langsyntaxhighlight lang="python">import sys
 
class UserInput:
Line 1,067 ⟶ 1,146:
 
uiList = getUserInput()
decode("theRaven.txt", uiList)</langsyntaxhighlight>
{{out}}
<pre>Silence-Dogood.</pre>
Line 1,075 ⟶ 1,154:
{{trans|Kotlin}}
 
<langsyntaxhighlight lang="racket">#lang racket
 
(define user-input
Line 1,097 ⟶ 1,176:
(define c (decode slice))
#:break (char=? #\! c)
(display c))</langsyntaxhighlight>
 
{{in}}
Line 1,106 ⟶ 1,185:
Silence-Dogood.
</pre>
 
=={{header|Raku}}==
(formerly Perl 6)
{{works with|Rakudo|2019.03}}
 
This is a something of a toy encoder / decoder and probably shouldn't be used for anything serious.
 
Default encode/decode key is 'Raku' Feed it a pass phrase at the command line to use that instead.
 
Will handle any visible character in the ASCII range as well as space and new-line.
 
<syntaxhighlight lang="raku" line>#`[
Set srand to set the encode / decode "key".
Need to use the same "key" and same implementation
of Raku to encode / decode. Gain "security" by
exchanging "keys" by a second channel. Default
"key" is "Raku"
]
 
unit sub MAIN ($key = 'Raku');
 
srand $key.comb(/<.alnum>/).join.parse-base(36) % 2**63;
 
my @stream = (flat "\n", ' ' .. '~').roll(*);
 
sub jit-encode (Str $str) {
my $i = 0;
my $last = 0;
my $enc = '';
for $str.comb -> $c {
my $h;
my $l = '';
++$i until $i > 1 && $c eq @stream[$i];
my $o = $i - $last;
$l = $o % 26;
$h = $o - $l if $o >= 26;
$l += 10;
$enc ~= ($h ?? $h.base(36).uc !! '') ~ ($l.base(36).lc);
$last = $i;
}
my $block = 60;
$enc.comb($block).join: "\n"
}
 
sub jit-decode (Str $str is copy) {
$str.=subst("\n", '', :g);
$str ~~ m:g/((.*?) (<:Ll>))/;
my $dec = '';
my $i = 0;
for $/.List -> $l {
my $o = ($l[0][1].Str.parse-base(36) - 10 // 0) +
($l[0][0].Str.parse-base(36) // 0);
$i += $o;
$dec ~= @stream[$i];
}
$dec
}
 
my $secret = q:to/END/;
In my opinion, this task is pretty silly.
 
'Twas brillig, and the slithy toves
Did gyre and gimble in the wabe.
 
!@#$%^&*()_+}{[].,><\|/?'";:1234567890
END
 
say "== Secret: ==\n$secret";
 
say "\n== Encoded: ==";
say my $enc = jit-encode($secret);
 
say "\n== Decoded: ==";
say jit-decode($enc);</syntaxhighlight>
 
<pre>== Secret: ==
In my opinion, this task is pretty silly.
 
'Twas brillig, and the slithy toves
Did gyre and gimble in the wabe.
 
!@#$%^&*()_+}{[].,><\|/?'";:1234567890
 
 
== Encoded: ==
Qv26e26q1Gi2Ww5SiQr26h3Mk1GbQy52e1Gg6Ib52kQfQk26n26l26cQm26q
2Wk26vwme52qy6Ia1GuQfa3MbQxtd26aa3MvQu2Wuat26p2Wbe2Wc1Ga26g2
6h26pQha26h4Cf26jrz7Yz3MaA4h2WxFWf52zyg2WrQn2Wj26pQyQy78x1Gd
dk4Cu26k26qaaap26j26xqQf7Yr8Op3Me3Me5Sv1Ge1Gt2WxlQz5Si1GeQg4
CjQc5Sb2WbQo1GycQr1Gm1Gy1GsQei3MrQsai1Gq2WnQdt2Wj1Gff1Gg26le
2Wd1Go9Ek1Gm9Eh2Wb1Gd52h2WdQae4Chu3MeQd1Gg1Gw4CqbEGh52u2Wr1G
t52xhvQmx
 
== Decoded: ==
In my opinion, this task is pretty silly.
 
'Twas brillig, and the slithy toves
Did gyre and gimble in the wabe.
 
!@#$%^&*()_+}{[].,><\|/?'";:1234567890</pre>
 
=={{header|REXX}}==
The input file used by this REXX program only contains one page; &nbsp; it has no &nbsp; ''FF'' &nbsp; (''formfeed'') &nbsp; characters in it),
<br>and the injection of &nbsp; ''FF'' &nbsp; characters into the file would be like putting pencil marks into a holy book. &nbsp; <big><big><big> ☺ </big></big></big>
<langsyntaxhighlight lang="rexx">/*REXX program extracts characters by using a book cipher (that is a text file). */
parse arg iFID . /*obtain optional name of file (book).*/
if iFID=='' | iFID=="," then iFID= 'JIT.TXT' /*Not specified? Then use the default.*/
Line 1,144 ⟶ 1,323:
?= ? || x /*append the character to the phrase. */
end /*j*/ /* [↑] display letters found in book. */
say '═════►' ? /*stick a fork in it, we're all done. */</langsyntaxhighlight>
{{out|input|text=&nbsp; supplied to the console (terminal) by the user in response to the prompts, &nbsp; (the commas are optional):}}
<pre>
Line 1,176 ⟶ 1,355:
=={{header|Tcl}}==
{{works with|Tcl|8.6}}
<langsyntaxhighlight lang="tcl">package require Tcl 8.6
 
oo::class create JustInTimeStreamExtract {
Line 1,245 ⟶ 1,424:
tcl::mathop::== $counter $counters(page) $counters(line) $counters(field) $counters(char)
}
}</langsyntaxhighlight>
Demonstration of use:
<langsyntaxhighlight lang="tcl">[JustInTimeStreamExtract new] stream [open "sample.txt"]</langsyntaxhighlight>
<!-- no output; I'll wait for someone else to invent something to decode… -->
 
=={{header|Visual Basic .NET}}==
{{trans|C#}}
<syntaxhighlight lang="vbnet">Module Module1
 
Structure UserInput
ReadOnly FormFeed As Char
ReadOnly LineFeed As Char
ReadOnly Tab As Char
ReadOnly Space As Char
 
Sub New(ff As String, lf As String, tb As String, sp As String)
FormFeed = ChrW(Integer.Parse(ff))
LineFeed = ChrW(Integer.Parse(lf))
Tab = ChrW(Integer.Parse(tb))
Space = ChrW(Integer.Parse(sp))
End Sub
End Structure
 
Function GetUserInput() As List(Of UserInput)
Dim h = "0 18 0 0 0 68 0 1 0 100 0 32 0 114 0 45 0 38 0 26 0 16 0 21 0 17 0 59 0 11 " &
"0 29 0 102 0 0 0 10 0 50 0 39 0 42 0 33 0 50 0 46 0 54 0 76 0 47 0 84 2 28"
Return h.Split(" ") _
.Select(Function(x, idx) New With {x, idx}) _
.GroupBy(Function(x) x.idx \ 4) _
.Select(Function(g)
Dim ge = g.Select(Function(a) a.x).ToArray()
Return New UserInput(ge(0), ge(1), ge(2), ge(3))
End Function) _
.ToList()
End Function
 
Sub Decode(filename As String, uiList As List(Of UserInput))
Dim text = IO.File.ReadAllText(filename)
 
Dim Inc = Function(a As Char) As Char
Return ChrW(AscW(a) + 1)
End Function
 
Dim DecodeImpl = Function(ui As UserInput) As Boolean
Dim f = ChrW(0)
Dim l = ChrW(0)
Dim t = ChrW(0)
Dim s = ChrW(0)
 
For Each c In text
If f = ui.FormFeed AndAlso l = ui.LineFeed AndAlso t = ui.Tab AndAlso s = ui.Space Then
If c = "!" Then
Return False
End If
Console.Write(c)
Return True
End If
If vbFormFeed = c Then
f = Inc(f)
l = ChrW(0)
t = ChrW(0)
s = ChrW(0)
ElseIf vbLf = c Then
l = Inc(l)
t = ChrW(0)
s = ChrW(0)
ElseIf vbTab = c Then
t = Inc(t)
s = ChrW(0)
Else
s = Inc(s)
End If
Next
 
Return False
End Function
 
For Each ui In uiList
If Not DecodeImpl(ui) Then
Exit For
End If
Next
 
Console.WriteLine()
End Sub
 
Sub Main()
Dim uiList = GetUserInput()
Decode("theRaven.txt", uiList)
End Sub
 
End Module</syntaxhighlight>
{{out}}
<pre>Silence-Dogood.</pre>
 
=={{header|Wren}}==
{{trans|Kotlin}}
{{libheader|Wren-dynamic}}
{{libheader|wren-seq}}
<syntaxhighlight lang="wren">import "io" for File
import "./dynamic" for Tuple
import "./seq" for Lst
 
var UserInput = Tuple.create("UserINput", ["formFeed", "lineFeed", "tab", "space"])
 
var getUserInput = Fn.new {
var h = "0 18 0 0 0 68 0 1 0 100 0 32 0 114 0 45 0 38 0 26 0 16 0 21 0 17 0 59 0 11 " +
"0 29 0 102 0 0 0 10 0 50 0 39 0 42 0 33 0 50 0 46 0 54 0 76 0 47 0 84 2 28"
return Lst.chunks(h.split(" "), 4).map { |chunk|
var flts = chunk.map { |c| Num.fromString(c) }.toList
return UserInput.new(flts[0], flts[1], flts[2], flts[3])
}
}
 
var decode = Fn.new { |fileName, uiList|
var text = File.read(fileName)
 
var decode2 = Fn.new { |ui|
var f = 0
var l = 0
var t = 0
var s = 0
for (c in text) {
if (f == ui.formFeed && l == ui.lineFeed && t == ui.tab && s == ui.space) {
if (c == "!") return false
System.write(c)
return true
}
if (c == "\f") {
f = f + 1
l = 0
t = 0
s = 0
} else if (c == "\n") {
l = l + 1
t = 0
s = 0
} else if (c == "\t") {
t = t + 1
s = 0
} else {
s = s + 1
}
}
return false
}
 
for (ui in uiList) if (!decode2.call(ui)) break
System.print()
}
 
var uiList = getUserInput.call()
decode.call("theRaven.txt", uiList)</syntaxhighlight>
 
{{out}}
<pre>
Silence-Dogood.
</pre>
 
=={{header|zkl}}==
{{trans|C++}}
<langsyntaxhighlight lang="zkl">class FlyBy{
fcn decode(file,tuplets){
codePad:=File(file).read().mode(String); // blob of text
Line 1,276 ⟶ 1,609:
h.split(" ").pump(List,T(Void.Read,3),
fcn(ff,lf,t,s){ vm.arglist.apply("toInt") });
}</langsyntaxhighlight>
<langsyntaxhighlight lang="zkl">input:=getUserInput();
// our code pad is: http://paulo-jorente.de/text/theRaven.txt
FlyBy.decode("theRaven.txt",input);</langsyntaxhighlight>
{{out}}
<pre>
1,481

edits