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

m
→‎{{header|11l}}: new way of specifying file open mode
No edit summary
m (→‎{{header|11l}}: new way of specifying file open mode)
 
(34 intermediate revisions by 12 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++}}
<syntaxhighlight lang="c">#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
 
struct UserInput {
char formFeed;
char lineFeed;
char tab;
char space;
};
 
struct UserInputNode {
struct UserInput ui;
struct UserInputNode *next;
};
 
bool decode(FILE *fp, const struct UserInput ui) {
char f = 0, l = 0, t = 0, s = 0;
char buffer[1];
 
while (fread(buffer, 1, 1, fp)) {
char c = buffer[0];
 
if (f == ui.formFeed && l == ui.lineFeed && t == ui.tab && s == ui.space) {
if (c == '!')
return false;
putchar(c);
return true;
} else if (c == '\f') {
f++;
l = t = s = 0;
} else if (c == '\n') {
l++;
t = s = 0;
} else if (c == '\t') {
t++;
s = 0;
} else {
s++;
}
}
 
return false;
}
 
void decodeFile(char *fileName, struct UserInputNode *uin) {
FILE *fp;
 
fp = fopen(fileName, "r");
if (NULL == fp) {
fprintf(stderr, "Could not find %s\n", fileName);
return;
}
 
if (NULL == uin) {
fprintf(stderr, "No user input detected!\n");
return;
}
 
while (NULL != uin) {
if (!decode(fp, uin->ui)) {
break;
}
fseek(fp, 0, SEEK_SET);
uin = uin->next;
}
printf("\n\n");
}
 
struct UserInputNode *getUserInput() {
struct UserInputNode *uip, *temp;
 
// 0 18 0 0
temp = malloc(sizeof(struct UserInputNode));
temp->ui.formFeed = 0;
temp->ui.lineFeed = 18;
temp->ui.tab = 0;
temp->ui.space = 0;
uip = temp;
 
// 0 68 0 1
temp->next = malloc(sizeof(struct UserInputNode));
temp = temp->next;
temp->ui.formFeed = 0;
temp->ui.lineFeed = 68;
temp->ui.tab = 0;
temp->ui.space = 1;
 
// 0 100 0 32
temp->next = malloc(sizeof(struct UserInputNode));
temp = temp->next;
temp->ui.formFeed = 0;
temp->ui.lineFeed = 100;
temp->ui.tab = 0;
temp->ui.space = 32;
 
// 0 114 0 45
temp->next = malloc(sizeof(struct UserInputNode));
temp = temp->next;
temp->ui.formFeed = 0;
temp->ui.lineFeed = 114;
temp->ui.tab = 0;
temp->ui.space = 45;
 
// 0 38 0 26
temp->next = malloc(sizeof(struct UserInputNode));
temp = temp->next;
temp->ui.formFeed = 0;
temp->ui.lineFeed = 38;
temp->ui.tab = 0;
temp->ui.space = 26;
 
// 0 16 0 21
temp->next = malloc(sizeof(struct UserInputNode));
temp = temp->next;
temp->ui.formFeed = 0;
temp->ui.lineFeed = 16;
temp->ui.tab = 0;
temp->ui.space = 21;
 
// 0 17 0 59
temp->next = malloc(sizeof(struct UserInputNode));
temp = temp->next;
temp->ui.formFeed = 0;
temp->ui.lineFeed = 17;
temp->ui.tab = 0;
temp->ui.space = 59;
 
// 0 11 0 29
temp->next = malloc(sizeof(struct UserInputNode));
temp = temp->next;
temp->ui.formFeed = 0;
temp->ui.lineFeed = 11;
temp->ui.tab = 0;
temp->ui.space = 29;
 
// 0 102 0 0
temp->next = malloc(sizeof(struct UserInputNode));
temp = temp->next;
temp->ui.formFeed = 0;
temp->ui.lineFeed = 102;
temp->ui.tab = 0;
temp->ui.space = 0;
 
// 0 10 0 50
temp->next = malloc(sizeof(struct UserInputNode));
temp = temp->next;
temp->ui.formFeed = 0;
temp->ui.lineFeed = 10;
temp->ui.tab = 0;
temp->ui.space = 50;
 
// 0 39 0 42
temp->next = malloc(sizeof(struct UserInputNode));
temp = temp->next;
temp->ui.formFeed = 0;
temp->ui.lineFeed = 39;
temp->ui.tab = 0;
temp->ui.space = 42;
 
// 0 33 0 50
temp->next = malloc(sizeof(struct UserInputNode));
temp = temp->next;
temp->ui.formFeed = 0;
temp->ui.lineFeed = 33;
temp->ui.tab = 0;
temp->ui.space = 50;
 
// 0 46 0 54
temp->next = malloc(sizeof(struct UserInputNode));
temp = temp->next;
temp->ui.formFeed = 0;
temp->ui.lineFeed = 46;
temp->ui.tab = 0;
temp->ui.space = 54;
 
// 0 76 0 47
temp->next = malloc(sizeof(struct UserInputNode));
temp = temp->next;
temp->ui.formFeed = 0;
temp->ui.lineFeed = 76;
temp->ui.tab = 0;
temp->ui.space = 47;
 
// 0 84 2 28
temp->next = malloc(sizeof(struct UserInputNode));
temp = temp->next;
temp->ui.formFeed = 0;
temp->ui.lineFeed = 84;
temp->ui.tab = 2;
temp->ui.space = 28;
 
temp->next = NULL;
return uip;
}
 
void freeUserInput(struct UserInputNode *uip) {
if (NULL == uip) {
return;
}
 
freeUserInput(uip->next);
uip->next = NULL;
 
free(uip);
}
 
int main() {
struct UserInputNode *uip;
 
uip = getUserInput();
decodeFile("theRaven.txt", uip);
freeUserInput(uip);
 
return 0;
}</syntaxhighlight>
{{out}}
<pre>Silence-Dogood.</pre>
 
=={{header|C sharp|C#}}==
{{trans|D}}
<syntaxhighlight lang="csharp">using System;
using System.Collections.Generic;
using System.Linq;
 
namespace JustInTimeProcessing {
struct UserInput {
public UserInput(string ff, string lf, string tb, string sp) {
FormFeed = (char)int.Parse(ff);
LineFeed = (char)int.Parse(lf);
Tab = (char)int.Parse(tb);
Space = (char)int.Parse(sp);
}
 
public char FormFeed { get; }
public char LineFeed { get; }
public char Tab { get; }
public char Space { get; }
}
 
class Program {
static List<UserInput> GetUserInput() {
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";
return h.Split(' ')
.Select((x, idx) => new { x, idx })
.GroupBy(x => x.idx / 4)
//.Select(g => g.Select(a => a.x))
.Select(g => {
var ge = g.Select(a => a.x).ToArray();
return new UserInput(ge[0], ge[1], ge[2], ge[3]);
})
.ToList();
}
 
static void Decode(string filename, List<UserInput> uiList) {
string text = System.IO.File.ReadAllText(filename);
 
bool Decode2(UserInput ui) {
char f = (char)0;
char l = (char)0;
char t = (char)0;
char s = (char)0;
 
foreach (char c in text) {
if (f == ui.FormFeed && l == ui.LineFeed && t == ui.Tab && s == ui.Space) {
if (c == '!') return false;
Console.Write(c);
return true;
}
if (c == '\u000c') {
f++; l = (char)0; t = (char)0; s = (char)0;
} else if (c == '\n') {
l++; t = (char)0; s = (char)0;
} else if (c == '\t') {
t++; s = (char)0;
} else {
s++;
}
}
 
return false;
}
 
foreach (UserInput ui in uiList) {
if (!Decode2(ui)) {
break;
}
}
Console.WriteLine();
}
 
static void Main(string[] args) {
var uiList = GetUserInput();
Decode("theraven.txt", uiList);
 
Console.ReadLine();
}
}
}</syntaxhighlight>
{{out}}
<pre>Silence-Dogood.</pre>
 
=={{header|C++}}==
Text used to encode:[http://paulo-jorente.de/text/theRaven.txt The Raven - by E.A.Poe]
<langsyntaxhighlight lang="cpp">
#include <vector>
#include <iostream>
Line 75 ⟶ 454:
return 0;
}
</syntaxhighlight>
</lang>
{{out}}
<pre>
Silence-Dogood.
</pre>
 
=={{header|D}}==
{{trans|Kotlin}}
<syntaxhighlight lang="d">import std.algorithm;
import std.array;
import std.conv;
import std.file;
import std.range;
import std.stdio;
 
struct UserInput {
char formFeed;
char lineFeed;
char tab;
char space;
 
this(string ff, string lf, string tb, string sp) {
formFeed = cast(char) ff.to!int;
lineFeed = cast(char) lf.to!int;
tab = cast(char) tb.to!int;
space = cast(char) sp.to!int;
}
}
 
auto getUserInput() {
auto 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";
auto ctor = (string[] a) => UserInput(a[0], a[1], a[2], a[3]);
return h.split(' ').chunks(4).map!ctor.array;
}
 
void decode(string fileName, UserInput[] uiList) {
auto text = readText(fileName);
 
bool decode2(UserInput ui) {
char f = 0;
char l = 0;
char t = 0;
char s = 0;
foreach (c; text) {
if (f == ui.formFeed && l == ui.lineFeed && t == ui.tab && s == ui.space) {
if (c == '!') return false;
write(c);
return true;
}
if (c == '\u000c') {
f++; l=0; t=0; s=0;
} else if (c == '\n') {
l++; t=0; s=0;
} else if (c == '\t') {
t++; s=0;
} else {
s++;
}
}
return false;
}
 
foreach (ui; uiList) {
if (!decode2(ui)) break;
}
writeln;
}
 
void main() {
auto uiList = getUserInput();
decode("theRaven.txt", uiList);
}</syntaxhighlight>
{{out}}
<pre>Silence-Dogood.</pre>
 
=={{header|Go}}==
{{trans|C++}}
<syntaxhighlight lang="go">package main
 
import (
"fmt"
"io/ioutil"
"log"
"strconv"
"strings"
)
 
type userInput struct{ formFeed, lineFeed, tab, space int }
 
func getUserInput() []userInput {
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"
flds := strings.Fields(h)
var uis []userInput
var uif [4]int
for i := 0; i < len(flds); i += 4 {
for j := 0; j < 4; j++ {
uif[j], _ = strconv.Atoi(flds[i+j])
}
uis = append(uis, userInput{uif[0], uif[1], uif[2], uif[3]})
}
return uis
}
 
func decode(fileName string, uis []userInput) error {
text, err := ioutil.ReadFile(fileName)
if err != nil {
return err
}
 
decode2 := func(ui userInput) bool {
var f, l, t, s int
for _, c := range text {
if f == ui.formFeed && l == ui.lineFeed && t == ui.tab && s == ui.space {
if c == '!' {
return false
}
fmt.Printf("%c", c)
return true
}
switch c {
case '\f':
f++
l = 0
t = 0
s = 0
case '\n':
l++
t = 0
s = 0
case '\t':
t++
s = 0
default:
s++
}
}
return true
}
 
for _, ui := range uis {
if !decode2(ui) {
break
}
}
fmt.Println()
return nil
}
 
func main() {
uis := getUserInput()
err := decode("theRaven.txt", uis)
if err != nil {
log.Fatal(err)
}
}</syntaxhighlight>
 
{{out}}
<pre>
Silence-Dogood.
</pre>
 
=={{header|Java}}==
{{trans|Kotlin}}
<syntaxhighlight lang="java">import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Predicate;
 
public class Processing {
private static class UserInput {
private char formFeed;
private char lineFeed;
private char tab;
private char space;
 
private UserInput(char formFeed, char lineFeed, char tab, char space) {
this.formFeed = formFeed;
this.lineFeed = lineFeed;
this.tab = tab;
this.space = space;
}
 
char getFormFeed() {
return formFeed;
}
 
char getLineFeed() {
return lineFeed;
}
 
char getTab() {
return tab;
}
 
char getSpace() {
return space;
}
}
 
private static List<UserInput> getUserInput() {
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";
String[] s = h.split(" ");
 
List<UserInput> uiList = new ArrayList<>();
for (int idx = 0; idx + 3 < s.length; idx += 4) {
char c0 = (char) Integer.parseInt(s[idx + 0]);
char c1 = (char) Integer.parseInt(s[idx + 1]);
char c2 = (char) Integer.parseInt(s[idx + 2]);
char c3 = (char) Integer.parseInt(s[idx + 3]);
 
UserInput userInput = new UserInput(c0, c1, c2, c3);
uiList.add(userInput);
}
return uiList;
}
 
private static void decode(String fileName, List<UserInput> uiList) throws IOException {
Path path = Paths.get(fileName);
byte[] bytes = Files.readAllBytes(path);
String text = new String(bytes, StandardCharsets.UTF_8);
 
Predicate<UserInput> decode2 = (UserInput ui) -> {
char f = 0;
char l = 0;
char t = 0;
char s = 0;
char ff = ui.getFormFeed();
char lf = ui.getLineFeed();
char tb = ui.getTab();
char sp = ui.getSpace();
 
for (char c : text.toCharArray()) {
if (f == ff && l == lf && t == tb && s == sp) {
if (c == '!') {
return false;
}
System.out.print(c);
return true;
}
switch (c) {
case '\u000c':
f++;
l = 0;
t = 0;
s = 0;
break;
case '\n':
l++;
t = 0;
s = 0;
break;
case '\t':
t++;
s = 0;
break;
default:
s++;
break;
}
}
 
return false;
};
 
for (UserInput ui : uiList) {
if (!decode2.test(ui)) {
break;
}
}
System.out.println();
}
 
public static void main(String[] args) throws IOException {
List<UserInput> uiList = getUserInput();
decode("theRaven.txt", uiList);
}
}</syntaxhighlight>
{{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.
<syntaxhighlight lang="julia">@enum streamstate GET_FF GET_LF GET_TAB GET_CHAR ABORT
chars = Dict(GET_FF => ['\f'], GET_LF => ['\n'], GET_TAB => ['\t'])
 
function stream_decode_jit(iostream)
msg, state, ffcount, lfcount, tabcount, charcount = "", GET_FF, 0, 0, 0, 0
while true
if state == ABORT || eof(iostream)
return msg
end
ch = read(iostream, Char)
if state == GET_FF && ch in chars[GET_FF]
ffcount += 1
state = GET_LF
lfcount = 0
elseif state == GET_LF && ch in chars[GET_LF]
if (lfcount += 1) == ffcount
state = GET_TAB
tabcount = 0
end
elseif state == GET_TAB && ch in chars[GET_TAB]
if (tabcount += 1) == ffcount
state = GET_CHAR
charcount = 0
end
elseif state == GET_CHAR
if (charcount += 1) == ffcount
print(ch)
msg *= ch
if ch == '!'
state = ABORT
else
state = GET_FF
end
end
end
end
end
 
stream_decode_jit(open("filename.txt", "r"))
</syntaxhighlight>
 
=={{header|Kotlin}}==
{{trans|C++}}
<syntaxhighlight lang="scala">// version 1.2.10
 
import java.io.File
 
data class UserInput(val formFeed: Int, val lineFeed: Int, val tab: Int, val space: Int)
 
fun getUserInput(): List<UserInput> {
val 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(' ').chunked(4).map {
val (ff, lf, tb, sp) = it
UserInput(ff.toInt(), lf.toInt(), tb.toInt(), sp.toInt())
}
}
 
fun decode(fileName: String, uiList: List<UserInput>) {
val text = File(fileName).readText()
 
fun decode2(ui: UserInput): Boolean {
var f = 0
var l = 0
var t = 0
var s = 0
val (ff, lf, tb, sp) = ui
for (c in text) {
if (f == ff && l == lf && t == tb && s == sp) {
if (c == '!') return false
print(c)
return true
}
when (c) {
'\u000c' -> { f++; l = 0; t = 0; s = 0 }
'\n' -> { l++; t = 0; s = 0 }
'\t' -> { t++; s = 0 }
else -> { s++ }
}
}
return false
}
 
for (ui in uiList) {
if (!decode2(ui)) break
}
println()
}
 
fun main(args: Array<String>) {
val uiList = getUserInput()
decode("theRaven.txt", uiList)
}</syntaxhighlight>
 
{{out}}
<pre>
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|Raku}}
{{libheader|ntheory}}
<syntaxhighlight lang="perl">use strict;
use warnings;
use feature 'say';
use feature 'state';
 
use ntheory qw/fromdigits todigitstring/;
 
my $key = 'perl5';
srand fromdigits($key,36) % 2**63;
 
my @stream;
 
sub stream {
my($i) = shift;
state @chars;
push @chars, chr($_) for 14..127;
$stream[$i] = $chars[rand 1+127-14] unless $stream[$i];
}
 
sub jit_encode {
my($str) = shift;
my $i = 0;
my $last = 0;
my $enc = '';
for my $c (split '', $str) {
my $h;
my $l = '';
++$i until $c eq stream($i);
my $o = $i - $last;
$l = $o % 26;
$h = $o - $l if $o > 26;
$l += 10;
$enc .= ($h ? uc todigitstring($h,36) : '') . lc todigitstring($l,36);
$last = $i;
}
$enc
}
 
sub jit_decode {
my($str) = shift;
my @matches = $str =~ /((.*?) ([a-z]))/gx;
my $dec = '';
my $i = 0;
for my $j (0 .. @matches/3 - 1) {
my $o = ( fromdigits($matches[3*$j+1],36) - 10 // 0) +
( fromdigits($matches[3*$j+2],36) // 0);
$i += $o;
$dec .= $stream[$i];
}
$dec
}
 
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);</syntaxhighlight>
{{out}}
<pre>Encoded
bQh52yf9Ex2Wi4Cv1GcyoAUcBKbke3Mo5Ss2WybQlvQs1GviQc1GnQg5Sv26j1Gm26m3Mp26iQz78lQx2Wel1Gcs52y5Sds3Me26l52au1Gwe1Gl
 
Decoded
The slithey toves did gyre and gimble in the wabe</pre>
 
=={{header|Phix}}==
{{trans|C}}
{{libheader|Phix/libcurl}}
<!--<syntaxhighlight lang="phix">(notonline)-->
<span style="color: #000080;font-style:italic;">-- demo/rosetta/BookCipher.exw</span>
<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>
<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>
<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>
<span style="color: #008080;">while</span> <span style="color: #004600;">true</span> <span style="color: #008080;">do</span>
<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>
<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>
<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>
<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>
<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>
<span style="color: #008080;">return</span> <span style="color: #004600;">true</span>
<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>
<span style="color: #000000;">f</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
<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>
<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>
<span style="color: #000000;">l</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</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: #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>
<span style="color: #000000;">t</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
<span style="color: #000000;">s</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
<span style="color: #008080;">else</span>
<span style="color: #000000;">s</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
<span style="color: #008080;">return</span> <span style="color: #004600;">false</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<span style="color: #000000;">error</span> <span style="color: #0000FF;">&=</span> <span style="color: #008000;">" [CURLE_COULDNT_RESOLVE_HOST]"</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<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>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<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>
<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>
<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>
<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>
<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>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
Silence-Dogood.
</pre>
 
=={{header|Python}}==
{{trans|D}}
<syntaxhighlight lang="python">import sys
 
class UserInput:
def __init__(self,chunk):
self.formFeed = int(chunk[0])
self.lineFeed = int(chunk[1])
self.tab = int(chunk[2])
self.space = int(chunk[3])
 
def __str__(self):
return "(ff=%d; lf=%d; tb=%d; sp%d)" % (self.formFeed,self.lineFeed,self.tab,self.space)
 
def chunks(l,n):
for i in xrange(0, len(l), n):
yield l[i:i+n]
 
def getUserInput():
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"
ha = h.split()
return [UserInput(chunk) for chunk in chunks(ha, 4)]
 
def decode(filename,uiList):
f = open(filename, "r")
text = f.read()
 
def decode2(ui):
f = 0
l = 0
t = 0
s = 0
for c in text:
if f == ui.formFeed and l == ui.lineFeed and t == ui.tab and s == ui.space:
if c == '!':
return False
sys.stdout.write(c)
return True
if c == '\u000c':
f=f+1
l=0
t=0
s=0
elif c == '\n':
l=l+1
t=0
s=0
elif c == '\t':
t=t+1
s=0
else:
s=s+1
return False
 
for ui in uiList:
if not decode2(ui):
break
print
 
##### Main #####
 
uiList = getUserInput()
decode("theRaven.txt", uiList)</syntaxhighlight>
{{out}}
<pre>Silence-Dogood.</pre>
 
=={{header|Racket}}==
 
{{trans|Kotlin}}
 
<syntaxhighlight lang="racket">#lang racket
 
(define user-input
(~a "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"))
 
(define content (file->string "theRaven.txt"))
 
(define (decode slice)
(match-define (list ff lf tb sp) slice)
(let loop ([f 0] [l 0] [t 0] [s 0] [xs (string->list content)])
(define next (curryr loop (rest xs)))
(match (first xs)
[c #:when (and (= f ff) (= l lf) (= t tb) (= s sp)) c]
[#\u000c (next (add1 f) 0 0 0)]
[#\newline (next f (add1 l) 0 0)]
[#\tab (next f l (add1 t) 0)]
[_ (next f l t (add1 s))])))
 
(for ([slice (in-slice 4 (map string->number (string-split user-input)))])
(define c (decode slice))
#:break (char=? #\! c)
(display c))</syntaxhighlight>
 
{{in}}
http://paulo-jorente.de/text/theRaven.txt
 
{{out}}
<pre>
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'' or&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 pgmprogram extracts characters by using a book cipher from (that is a text file). */
parse arg iFID . /*obtain optional name of file (book). */
if iFID=='' then| iFID=="JIT.TXT," then iFID= 'JIT.TXT' /*Not specified? Then use the default.*/
$= 'abcdefghijklmnopqrstuvwxyz'; _=$; upper _; $= "0123456789"$ || _; $$=$ || xrange()
errTxt= ' is missing or not a positive integer: ' /*error text string.*/
prompt= '────────── enter four positive integers or Quit'
$='abcdefghijklmnopqrstuvwxyz'; _=$; upper _; $= '0123456789'$ || _
pag=1; lin=1; FF= 'c'x /*assume start of page 1, line 1. */
ask='──────────enter four parameters (all positive integers) or QUIT'
pag@.=1; lin=1; @.= /*assumeread startthe ofentire pagebook 1,from linethe 1file. */
do while lines(iFID)\==0 /*readprocess thelines entirefrom book frominput stream(file.)*/
do_= translate( while lineslinein(iFID)\==0, , '9'x) /*processobtain a single linesline from input streamfile.*/
if pos(FF, _)\==0 then do; pag=pag+1; lin=1 /*bump page counter; reset line counter*/
_=translate(linein(iFID),,'9'x) /*obtain a single line from input*/
end /* [↑] handle finding of FF (formfeed)*/
if pos('c'x,_)\==0 then do /*was a ff (form-feed) detected? */
@.pag.lin= _ pag=pag+1 /*bumpobtain a pagesingle counterline forfrom nextinput pagefile.*/
lin= lin + 1 lin=1 /*resetbump the line counter. to one. */
end /*while*/ end /* [↑] handle findingread the entire input stream. of formfeed*/
?= @.pag.lin=_ /*obtaindefine the phrase ato singlebe linenull from(so inputfar)*/
lin=lin+1 do ask=0; say prompt; pull y /*bumpget thejust─in─time linepositional counternumbers. */
end /*whileif lines···*/abbrev('QUIT', y, 1) then exit 0 /*the [↑]user wants readout entireof inputhere, streamso exit. */
?= y=space( translate(y, $, $$) ) /*defineallow theany separator phrasethe user towants. be null.*/
doparse prompt=0;var bad= y a.1 a.2 a.3 a.4 /*getparse J.I.T.the positionalpertinent numbersparameters. */
if words(y)>4 then do; say 'too many parameters entered.'
say ask; pull y /*obtain the numbers from console*/
if y='QUIT' then exit 0 /*the user wants out of this loop*/ iterate ask
y=space(translate(y,$,$||xrange())) end /*allowgo and try again anyto sepobtain userthe wantsparms.*/
parse var do yk=1 a.1for a.24; a.3 is#= datatype(a.4 k, 'W') /*parsevalidate parms the pertinent{positive parametersintegers}.*/
if is# then a.1=k='QUIT' a.k / 1 then exit 0 /*normalize the usernumber wants(for out of thisindexing). loop*/
if words(y)>4is# & a.k>0 then doiterate /*didfound thea usergood haveparameter? fingeritis ? Then skip. */
say 'parameter ' k " is missing or not saya 'toopositive manyinteger: parameters" entered a.'k
iterate ask iterate prompt /*go and ask for another set of parms. */
end /*k*/ end /*go and[↑] try againdone towith getthe parmsvalidations. */
parse value do k=a.1 a.2 fora.3 a.4 with p L w c /*validateparse parmsparameters {positivefor ints}specific names. */
x=substr( if datatypeword(a @.kp.L,'W' w), c, 1) & a.k>0 then iterate /*foundextract a badcharacter parmfrom the book. */
if x=='!' then leave /*if the stop char was found, done. */
say 'parameter ' k errTxt a.k /*issue an error message to term.*/
say iterate prompt right(x '◄─── a letter', 46) /*gomight &as askwell forecho anotherchar setto ofterminal. #s.*/
?= ? || x a.k=a.k/1 /*normalizeappend the user'scharacter number.to the phrase. */
end /*kj*/ /* [↑] donedisplay letters found within thebook. validations*/
say '═════►' ? parse var y p l w c /*parsestick parametersa forfork names.in it, we're all done. */</syntaxhighlight>
{{out|input|text=&nbsp; supplied to the console (terminal) by the user in response to the prompts, &nbsp; (the commas are optional):}}
x=substr(word(@.p.l,w),c,1) /*extract the character from book*/
if x=='!' then leave /*if the stop char found, done.*/
say right(x '◄─── a letter',46) /*might as well echo char to term*/
?=? || x /*append the character to phrase.*/
end /*j*/ /* [↑] go & keep building phrase*/
say '═════►' ? /*display letters found from book*/
/*stick a fork in it, we're done.*/</lang>
'''input''' &nbsp; supplied to the console (terminal) by the user &nbsp; (the commas are optional):
<pre>
1, 133, 4, 5
Line 138 ⟶ 1,336:
1, 571, 4, 12
</pre>
'''output''' {{out|input|text=&nbsp; (abbridged)}}
<pre>
──────────enter four parameters (all positive integers) or QUIT
1, 133, 4, 5 ◄■■■■■■■■■ user input (first reponse).
1, 133, 4, 5
s ◄─── a letter
──────────enter four parameters (all positive integers) or QUIT
 
·
∙ (some prompts and reponses elided.)
·
·
 
──────────enter four parameters (all positive integers) or QUIT
1, 571, 4, 12 ◄■■■■■■■■■ user input (ninth reponse).
═════► so─true.
</pre>
Line 156 ⟶ 1,355:
=={{header|Tcl}}==
{{works with|Tcl|8.6}}
<langsyntaxhighlight lang="tcl">package require Tcl 8.6
 
oo::class create JustInTimeStreamExtract {
Line 225 ⟶ 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++}}
<syntaxhighlight lang="zkl">class FlyBy{
fcn decode(file,tuplets){
codePad:=File(file).read().mode(String); // blob of text
tuplets.pump(Console.print, _decode.fp1(codePad));
println();
}
fcn [private] _decode(idx,codePad){ // idx is (ff,lf,tab,chr) offset info codePad
z:=-1;
foreach n,c in (idx.zip(T("\f","\n","\t"))){
do(n){ if(Void==(z=codePad.find(c,z+1))) return(Void.Stop); }
}
if(z==-1) z=0; // (0,0,0,n)
try{ return(codePad[z + idx[-1] + 1]) }catch{ return(Void.Stop) }
}
}
 
fcn getUserInput{
// I don't know a user would enter this but we have
// a string of 4 item tuplets : (formfeeds, linefeeds, tabs, characters), ...
// each tuplet is an offset into a code pad (text)
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";
h.split(" ").pump(List,T(Void.Read,3),
fcn(ff,lf,t,s){ vm.arglist.apply("toInt") });
}</syntaxhighlight>
<syntaxhighlight lang="zkl">input:=getUserInput();
// our code pad is: http://paulo-jorente.de/text/theRaven.txt
FlyBy.decode("theRaven.txt",input);</syntaxhighlight>
{{out}}
<pre>
Silence-Dogood.
</pre>
1,480

edits