Data update
This commit is contained in:
parent
4bb20c9b71
commit
cbaf4c4b64
12390 changed files with 318560 additions and 27248 deletions
|
|
@ -11,31 +11,31 @@ Num2 := InStr(board, A_Space) -1
|
|||
Num3 := InStr(board, A_Space, true, Num1+1) -1
|
||||
Loop Parse, Text
|
||||
{
|
||||
char := A_LoopField
|
||||
Loop Parse, board, `n
|
||||
{
|
||||
If (Pos := InStr(A_LoopField, char))
|
||||
out .= Num%A_Index% . Pos-1
|
||||
else if (Pos := InStr(A_LoopField, "/")) && InStr("0123456789", char)
|
||||
out .= Num%A_Index% . Pos-1 . char
|
||||
}
|
||||
char := A_LoopField
|
||||
Loop Parse, board, `n
|
||||
{
|
||||
If (Pos := InStr(A_LoopField, char))
|
||||
out .= Num%A_Index% . Pos-1
|
||||
else if (Pos := InStr(A_LoopField, "/")) && InStr("0123456789", char)
|
||||
out .= Num%A_Index% . Pos-1 . char
|
||||
}
|
||||
}
|
||||
MsgBox % out
|
||||
|
||||
i := 0
|
||||
While (LoopField := SubStr(out, ++i, 1)) <> ""
|
||||
{
|
||||
If (LoopField = num2) or (LoopField = num3)
|
||||
col := SubStr(out, ++i, 1)
|
||||
else col := 0
|
||||
Loop Parse, board, `n
|
||||
{
|
||||
If !col && A_Index = 1
|
||||
dec .= SubStr(A_LoopField, LoopField+1, 1)
|
||||
Else If (Num%A_Index% = LoopField) && col
|
||||
dec .= SubStr(A_LoopField, col+1, 1)
|
||||
If SubStr(dec, 0) = "/"
|
||||
dec := SubStr(dec, 1, StrLen(dec)-1) . SubStr(out, ++i, 1)
|
||||
}
|
||||
If (LoopField = num2) or (LoopField = num3)
|
||||
col := SubStr(out, ++i, 1)
|
||||
else col := 0
|
||||
Loop Parse, board, `n
|
||||
{
|
||||
If !col && A_Index = 1
|
||||
dec .= SubStr(A_LoopField, LoopField+1, 1)
|
||||
Else If (Num%A_Index% = LoopField) && col
|
||||
dec .= SubStr(A_LoopField, col+1, 1)
|
||||
If SubStr(dec, 0) = "/"
|
||||
dec := SubStr(dec, 1, StrLen(dec)-1) . SubStr(out, ++i, 1)
|
||||
}
|
||||
}
|
||||
MsgBox % dec
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ GHashTable *create_table_from_array(const char *table[ROWS][COLS], bool is_encod
|
|||
numprefix_col = i;
|
||||
numprefix_row = j;
|
||||
has_numprefix = true;
|
||||
break;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -92,21 +92,21 @@ GHashTable *create_table_from_array(const char *table[ROWS][COLS], bool is_encod
|
|||
if (table[i][j] == NULL) continue;
|
||||
if (strlen(table[i][j]) > 1)
|
||||
{
|
||||
fprintf(stderr, "symbols must be 1 byte long\n");
|
||||
continue; // we continue just ignoring the issue
|
||||
fprintf(stderr, "symbols must be 1 byte long\n");
|
||||
continue; // we continue just ignoring the issue
|
||||
}
|
||||
if (has_numprefix && i == (ROWS-1) && j == numprefix_col && i == numprefix_row) continue;
|
||||
if (has_numprefix && i == 0)
|
||||
{
|
||||
snprintf(buf, sizeof(buf), "%s%s%s", table[0][selectors[SELNUM-1]], table[0][numprefix_col], table[0][j]);
|
||||
snprintf(buf, sizeof(buf), "%s%s%s", table[0][selectors[SELNUM-1]], table[0][numprefix_col], table[0][j]);
|
||||
}
|
||||
else if (i == 1)
|
||||
{
|
||||
snprintf(buf, sizeof(buf), "%s", table[0][j]);
|
||||
snprintf(buf, sizeof(buf), "%s", table[0][j]);
|
||||
}
|
||||
else
|
||||
{
|
||||
snprintf(buf, sizeof(buf), "%s%s", table[0][selectors[i-2]], table[0][j]);
|
||||
snprintf(buf, sizeof(buf), "%s%s", table[0][selectors[i-2]], table[0][j]);
|
||||
}
|
||||
if (is_encoding) g_hash_table_insert(r, strdup(table[i][j]), strdup(buf));
|
||||
else g_hash_table_insert(r, strdup(buf), strdup(table[i][j]));
|
||||
|
|
@ -179,8 +179,8 @@ char *encode(GHashTable *et, const char *plaintext, int (*trasf)(int), bool comp
|
|||
else
|
||||
{
|
||||
fprintf(stderr, "char '%s' is not encodable%s\n",
|
||||
isprint(buf[0]) ? buf : "?",
|
||||
!compress_spaces ? ", replacing with a space" : "");
|
||||
isprint(buf[0]) ? buf : "?",
|
||||
!compress_spaces ? ", replacing with a space" : "");
|
||||
if (!compress_spaces) g_string_append_c(s, ' ');
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,49 @@
|
|||
def encrypt (board, message)
|
||||
prefixes = [""] + board.first.chars.each.with_index.select {|ch, _| ch == ' ' }.map(&.last.to_s).to_a
|
||||
encode_letter = ->(ch : Char) {
|
||||
col = nil
|
||||
row = board.index {|r| col = r.index ch}
|
||||
raise "incomplete board" unless col && row
|
||||
prefixes[row] + col.to_s
|
||||
}
|
||||
String.build do |s|
|
||||
message.each_char do |ch|
|
||||
if ch.ascii_number?
|
||||
s << encode_letter['/'] << ch
|
||||
else
|
||||
ch = ch.ascii_letter? ? ch.upcase : '.'
|
||||
s << encode_letter[ch]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def decrypt (board, message)
|
||||
prefixes = board.first.chars.each.with_index.select {|ch, _| ch == ' ' }.map {|ch, idx| '0' + idx}.to_a
|
||||
message = message.chars
|
||||
String.build do |s|
|
||||
i = 0
|
||||
while i < message.size
|
||||
row = prefixes.index(message[i])
|
||||
letter = if row
|
||||
board[row+1][message[i+=1].to_i]
|
||||
else
|
||||
board[0][message[i].to_i]
|
||||
end
|
||||
if letter == '/'
|
||||
s << message[i+=1]
|
||||
else
|
||||
s << letter
|
||||
end
|
||||
i += 1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
board = ["ET AON RIS", "BCDFGHJKLM", "PQ/UVWXYZ."]
|
||||
|
||||
original = "One night-it was on the twentieth of March, 1888-I was returning"
|
||||
coded = encrypt(board, original)
|
||||
decoded = decrypt(board, coded)
|
||||
|
||||
p! original, coded, decoded
|
||||
|
|
@ -1,8 +1,6 @@
|
|||
board$ = "ET AON RISBCDFGHJKLMPQ/UVWXYZ."
|
||||
len encode[] 128
|
||||
len decode$[] 128
|
||||
arrbase encode[] 0
|
||||
arrbase decode$[] 0
|
||||
len row[] 2
|
||||
proc init s$ .
|
||||
s$[] = strchars s$
|
||||
|
|
|
|||
|
|
@ -8,13 +8,13 @@ function straddle(message){
|
|||
message=message.replace(/([0-9])/g,"/$1") // dumb way to escape numbers
|
||||
for(var i=0;i<message.length;i++){
|
||||
var chr=message[i]
|
||||
if(chr==" ")continue
|
||||
for(var j=0;j<3;j++){
|
||||
var k=alphabet[j].indexOf(chr)
|
||||
if(k<0)continue
|
||||
out+=prefixes[j].toString()+k
|
||||
}
|
||||
if(chr=="/")out+=message[++i]
|
||||
if(chr==" ")continue
|
||||
for(var j=0;j<3;j++){
|
||||
var k=alphabet[j].indexOf(chr)
|
||||
if(k<0)continue
|
||||
out+=prefixes[j].toString()+k
|
||||
}
|
||||
if(chr=="/")out+=message[++i]
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
|
@ -23,13 +23,13 @@ function unstraddle(message){
|
|||
var out=""
|
||||
var n,o
|
||||
for(var i=0;i<message.length;i++){
|
||||
n=message[i]*1
|
||||
n=message[i]*1
|
||||
switch(n){
|
||||
case prefixes[1]: o=alphabet[1][message[++i]];break
|
||||
case prefixes[2]: o=alphabet[2][message[++i]];break
|
||||
default: o=alphabet[0][n]
|
||||
}
|
||||
o=="/"?out+=message[++i]:out+=o
|
||||
case prefixes[1]: o=alphabet[1][message[++i]];break
|
||||
case prefixes[2]: o=alphabet[2][message[++i]];break
|
||||
default: o=alphabet[0][n]
|
||||
}
|
||||
o=="/"?out+=message[++i]:out+=o
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,123 +1,123 @@
|
|||
module Straddling_checkerboard {
|
||||
function encrypt$(message$, alphabet) {
|
||||
message$=filter$(ucase$(message$),"-/,. ")
|
||||
def num1, num2
|
||||
num1=instr(alphabet#val$(0)," ")
|
||||
num2=instr(alphabet#val$(0)," ", num1+1)-1
|
||||
num1--
|
||||
escapenum=instr(alphabet#val$(2),"/")-1
|
||||
escapenum1=instr(alphabet#val$(2),".")-1
|
||||
num0=-10
|
||||
num10=num1*10-20
|
||||
num20=num2*10-30
|
||||
numbers=(escapenum+num2*10)*10
|
||||
numbers1=(escapenum1+num2*10)*10
|
||||
boardrow=each(alphabet)
|
||||
cipherkey$="0123456789" : while boardrow :cipherkey$+=array$(boardrow) :end while
|
||||
encoded$=""
|
||||
for i=1 to len(message$)
|
||||
n=instr(cipherkey$, mid$(message$,i,1))-1
|
||||
if n<10 then
|
||||
n+=if(random(10)<5->numbers, numbers1)
|
||||
else.if n<20 then
|
||||
n+=num0
|
||||
else.if n<30 then
|
||||
n+=num10
|
||||
else
|
||||
n+=num20
|
||||
end if
|
||||
encoded$+=str$(n,"")
|
||||
next
|
||||
=encoded$
|
||||
}
|
||||
function decrypt$(encoded$, alphabet) {
|
||||
def num1, num2
|
||||
num1=instr(alphabet#val$(0)," ")
|
||||
num2=instr(alphabet#val$(0)," ", num1+1)-1
|
||||
num1--
|
||||
escapenum=instr(alphabet#val$(2),"/")-1
|
||||
escapenum1=instr(alphabet#val$(2),".")-1
|
||||
def i=1, decoded$
|
||||
j=len(encoded$)+1
|
||||
while i<j
|
||||
m=val(mid$(encoded$,i,1))
|
||||
if m=num1 then
|
||||
decoded$+=mid$(alphabet#val$(1), val(mid$(encoded$,i+1,1))+1,1)
|
||||
i++
|
||||
else.if m=num2 then
|
||||
if i+1<j then
|
||||
mm=val(mid$(encoded$,i+1,1))
|
||||
if mm=escapenum or mm=escapenum1 then
|
||||
decoded$+=mid$(encoded$,i+2,1)
|
||||
i+=2
|
||||
else
|
||||
decoded$+=mid$(alphabet#val$(2), val(mid$(encoded$,i+1,1))+1,1)
|
||||
i++
|
||||
end if
|
||||
else
|
||||
decoded$+=mid$(alphabet#val$(2), val(mid$(encoded$,i+1,1))+1,1)
|
||||
i++
|
||||
end if
|
||||
else
|
||||
decoded$+=mid$(alphabet#val$(0), m+1,1)
|
||||
end if
|
||||
i++
|
||||
end while
|
||||
=decoded$
|
||||
}
|
||||
Module DisplayBoard (alphabet, &Doc$){
|
||||
num1=instr(alphabet#val$(0)," ")
|
||||
num2=instr(alphabet#val$(0)," ", num1+1)-1
|
||||
num1--
|
||||
escapenum=instr(alphabet#val$(2),"/")-1
|
||||
escapenum1=instr(alphabet#val$(2),".")-1
|
||||
\\ display straddling checkerboard
|
||||
checkerboard =cons(("0123456789",),alphabet)
|
||||
labels=(" "," ",str$(num1,""), str$(num2,""))
|
||||
disp=each(checkerboard)
|
||||
while disp
|
||||
Doc$=labels#val$(disp^)+" "+array$(disp)+{
|
||||
}
|
||||
end while
|
||||
}
|
||||
Document Doc$
|
||||
Const nl$={
|
||||
}
|
||||
Function OnePad$(Message$, PadSerial, n=1) {
|
||||
x=random(!PadSerial) ' push old seed, set the new one
|
||||
encoded$=""
|
||||
for i=1 to len(Message$)
|
||||
encoded$+=str$((val(mid$(Message$,i,1))+10+n*random(1, 10))mod 10,"")
|
||||
next i
|
||||
x=random(!) ' restore old seed
|
||||
=encoded$
|
||||
}
|
||||
\\ select a random alphabet
|
||||
select case random(1,3)
|
||||
case 1
|
||||
alphabet=("ESTONIAR ","BCDFGHJKLM","/PQUVWXYZ.") : Doc$="First "+nl$
|
||||
case 2
|
||||
alphabet=("ET AON RIS","BCDFGHJKLM","PQ/UVWXYZ.") : Doc$="Second"+nl$
|
||||
case 3
|
||||
alphabet=("ESTONIAR ","BCDFGHJKLM","PQU.VWXYZ/") : Doc$="Third"+nl$
|
||||
end select
|
||||
DisplayBoard alphabet, &Doc$
|
||||
msg$="One night-it was on the twentieth of March, 1888-I was returning"
|
||||
Doc$= "original message:"+nl$
|
||||
Doc$= msg$+nl$
|
||||
Doc$= "encrypted message:"+nl$
|
||||
crypt$=encrypt$(msg$, alphabet)
|
||||
Doc$=crypt$+nl$
|
||||
serial=random(1234567,9345678)
|
||||
Doc$= "encrypted message using one pad using serial:"+str$(serial)+nl$
|
||||
crypt$=OnePad$(crypt$, serial)
|
||||
Doc$=crypt$+nl$
|
||||
Doc$= "decrypted message using one pad:"+nl$
|
||||
crypt$=OnePad$(crypt$, serial,-1)
|
||||
Doc$=crypt$+nl$
|
||||
Doc$= "decrypted message:"+nl$
|
||||
Doc$=decrypt$(crypt$, alphabet)
|
||||
Print #-2, Doc$ ' render to console using new lines codes from Doc$
|
||||
Clipboard Doc$
|
||||
function encrypt$(message$, alphabet) {
|
||||
message$=filter$(ucase$(message$),"-/,. ")
|
||||
def num1, num2
|
||||
num1=instr(alphabet#val$(0)," ")
|
||||
num2=instr(alphabet#val$(0)," ", num1+1)-1
|
||||
num1--
|
||||
escapenum=instr(alphabet#val$(2),"/")-1
|
||||
escapenum1=instr(alphabet#val$(2),".")-1
|
||||
num0=-10
|
||||
num10=num1*10-20
|
||||
num20=num2*10-30
|
||||
numbers=(escapenum+num2*10)*10
|
||||
numbers1=(escapenum1+num2*10)*10
|
||||
boardrow=each(alphabet)
|
||||
cipherkey$="0123456789" : while boardrow :cipherkey$+=array$(boardrow) :end while
|
||||
encoded$=""
|
||||
for i=1 to len(message$)
|
||||
n=instr(cipherkey$, mid$(message$,i,1))-1
|
||||
if n<10 then
|
||||
n+=if(random(10)<5->numbers, numbers1)
|
||||
else.if n<20 then
|
||||
n+=num0
|
||||
else.if n<30 then
|
||||
n+=num10
|
||||
else
|
||||
n+=num20
|
||||
end if
|
||||
encoded$+=str$(n,"")
|
||||
next
|
||||
=encoded$
|
||||
}
|
||||
function decrypt$(encoded$, alphabet) {
|
||||
def num1, num2
|
||||
num1=instr(alphabet#val$(0)," ")
|
||||
num2=instr(alphabet#val$(0)," ", num1+1)-1
|
||||
num1--
|
||||
escapenum=instr(alphabet#val$(2),"/")-1
|
||||
escapenum1=instr(alphabet#val$(2),".")-1
|
||||
def i=1, decoded$
|
||||
j=len(encoded$)+1
|
||||
while i<j
|
||||
m=val(mid$(encoded$,i,1))
|
||||
if m=num1 then
|
||||
decoded$+=mid$(alphabet#val$(1), val(mid$(encoded$,i+1,1))+1,1)
|
||||
i++
|
||||
else.if m=num2 then
|
||||
if i+1<j then
|
||||
mm=val(mid$(encoded$,i+1,1))
|
||||
if mm=escapenum or mm=escapenum1 then
|
||||
decoded$+=mid$(encoded$,i+2,1)
|
||||
i+=2
|
||||
else
|
||||
decoded$+=mid$(alphabet#val$(2), val(mid$(encoded$,i+1,1))+1,1)
|
||||
i++
|
||||
end if
|
||||
else
|
||||
decoded$+=mid$(alphabet#val$(2), val(mid$(encoded$,i+1,1))+1,1)
|
||||
i++
|
||||
end if
|
||||
else
|
||||
decoded$+=mid$(alphabet#val$(0), m+1,1)
|
||||
end if
|
||||
i++
|
||||
end while
|
||||
=decoded$
|
||||
}
|
||||
Module DisplayBoard (alphabet, &Doc$){
|
||||
num1=instr(alphabet#val$(0)," ")
|
||||
num2=instr(alphabet#val$(0)," ", num1+1)-1
|
||||
num1--
|
||||
escapenum=instr(alphabet#val$(2),"/")-1
|
||||
escapenum1=instr(alphabet#val$(2),".")-1
|
||||
\\ display straddling checkerboard
|
||||
checkerboard =cons(("0123456789",),alphabet)
|
||||
labels=(" "," ",str$(num1,""), str$(num2,""))
|
||||
disp=each(checkerboard)
|
||||
while disp
|
||||
Doc$=labels#val$(disp^)+" "+array$(disp)+{
|
||||
}
|
||||
end while
|
||||
}
|
||||
Document Doc$
|
||||
Const nl$={
|
||||
}
|
||||
Function OnePad$(Message$, PadSerial, n=1) {
|
||||
x=random(!PadSerial) ' push old seed, set the new one
|
||||
encoded$=""
|
||||
for i=1 to len(Message$)
|
||||
encoded$+=str$((val(mid$(Message$,i,1))+10+n*random(1, 10))mod 10,"")
|
||||
next i
|
||||
x=random(!) ' restore old seed
|
||||
=encoded$
|
||||
}
|
||||
\\ select a random alphabet
|
||||
select case random(1,3)
|
||||
case 1
|
||||
alphabet=("ESTONIAR ","BCDFGHJKLM","/PQUVWXYZ.") : Doc$="First "+nl$
|
||||
case 2
|
||||
alphabet=("ET AON RIS","BCDFGHJKLM","PQ/UVWXYZ.") : Doc$="Second"+nl$
|
||||
case 3
|
||||
alphabet=("ESTONIAR ","BCDFGHJKLM","PQU.VWXYZ/") : Doc$="Third"+nl$
|
||||
end select
|
||||
DisplayBoard alphabet, &Doc$
|
||||
msg$="One night-it was on the twentieth of March, 1888-I was returning"
|
||||
Doc$= "original message:"+nl$
|
||||
Doc$= msg$+nl$
|
||||
Doc$= "encrypted message:"+nl$
|
||||
crypt$=encrypt$(msg$, alphabet)
|
||||
Doc$=crypt$+nl$
|
||||
serial=random(1234567,9345678)
|
||||
Doc$= "encrypted message using one pad using serial:"+str$(serial)+nl$
|
||||
crypt$=OnePad$(crypt$, serial)
|
||||
Doc$=crypt$+nl$
|
||||
Doc$= "decrypted message using one pad:"+nl$
|
||||
crypt$=OnePad$(crypt$, serial,-1)
|
||||
Doc$=crypt$+nl$
|
||||
Doc$= "decrypted message:"+nl$
|
||||
Doc$=decrypt$(crypt$, alphabet)
|
||||
Print #-2, Doc$ ' render to console using new lines codes from Doc$
|
||||
Clipboard Doc$
|
||||
}
|
||||
Straddling_checkerboard
|
||||
|
|
|
|||
|
|
@ -0,0 +1,83 @@
|
|||
local board = "ET AON RISBCDFGHJKLMPQ/UVWXYZ."
|
||||
local digits = "0123456789"
|
||||
local rows = " 26"
|
||||
local escape = "62"
|
||||
local key = "0452"
|
||||
|
||||
local function encrypt(message)
|
||||
local msg = message:upper():split("")
|
||||
:filtered(|c| -> (c in board or c in digits) and !(c in " /"))
|
||||
:reorder()
|
||||
local sb = ""
|
||||
for msg as c do
|
||||
local idx = board:find(c, 1, true)
|
||||
if idx then
|
||||
idx -= 1
|
||||
local row = idx // 10
|
||||
local col = idx % 10
|
||||
sb ..= (row == 0) ? $"{col}" : $"{rows[row + 1]}{col}"
|
||||
else
|
||||
sb ..= $"{escape}{c}"
|
||||
end
|
||||
end
|
||||
local enc = {sb:byte(1, #sb)}
|
||||
local i = 0
|
||||
for enc as c do
|
||||
local k = key[i % 4 + 1]:byte() - 48
|
||||
if k != 0 then
|
||||
local j = c - 48
|
||||
enc[i + 1] = 48 + ((j + k) % 10)
|
||||
end
|
||||
i += 1
|
||||
end
|
||||
|
||||
return enc:map(|b| -> string.char(b)):concat("")
|
||||
end
|
||||
|
||||
local function decrypt(encoded)
|
||||
local enc = {encoded:byte(1, #encoded)}
|
||||
local i = 0
|
||||
for enc as c do
|
||||
local k = key[i % 4 + 1]:byte() - 48
|
||||
if k != 0 then
|
||||
local j = c - 48
|
||||
enc[i + 1] = 48 + ((j >= k) ? (j - k) % 10 : (10 + j - k) % 10)
|
||||
end
|
||||
i += 1
|
||||
end
|
||||
local len = #enc
|
||||
local sb = ""
|
||||
i = 0
|
||||
while i < len do
|
||||
local c = enc[i + 1]
|
||||
local idx = rows:find(tostring(c - 48), 1, true)
|
||||
if !idx then
|
||||
local idx2 = c - 48
|
||||
sb ..= board[idx2 + 1]
|
||||
i += 1
|
||||
elseif $"{c - 48}{enc[i + 2] - 48}" == escape then
|
||||
sb ..= tostring(enc[i + 3] - 48)
|
||||
i += 3
|
||||
else
|
||||
local idx2 = (idx - 1) * 10 + enc[i + 2] - 48
|
||||
sb ..= board[idx2 + 1]
|
||||
i += 2
|
||||
end
|
||||
end
|
||||
return sb
|
||||
end
|
||||
|
||||
local messages = {
|
||||
"Attack at dawn",
|
||||
"One night-it was on the twentieth of March, 1888-I was returning",
|
||||
"In the winter 1965/we were hungry/just barely alive",
|
||||
"you have put on 7.5 pounds since I saw you.",
|
||||
"The checkerboard cake recipe specifies 3 large eggs and 2.25 cups of flour."
|
||||
}
|
||||
for messages as message do
|
||||
local encrypted = encrypt(message)
|
||||
local decrypted = decrypt(encrypted)
|
||||
print($"\nMessage : {message}")
|
||||
print($"Encrypted : {encrypted}")
|
||||
print($"Decrypted : {decrypted}")
|
||||
end
|
||||
|
|
@ -0,0 +1,78 @@
|
|||
Rebol [
|
||||
title: "Rosetta code: Straddling checkerboard"
|
||||
file: %Straddling_checkerboard.r3
|
||||
url: https://rosettacode.org/wiki/Straddling_checkerboard
|
||||
]
|
||||
|
||||
register-codec [
|
||||
name: 'straddle
|
||||
type: 'cryptography
|
||||
title: "Straddling checkerboard"
|
||||
|
||||
T: [
|
||||
["79" #"0" #"1" #"2" #"3" #"4" #"5" #"6" #"7" #"8" #"9"]
|
||||
["" #"H" #"O" #"L" "" #"M" #"E" #"S" "" #"R" #"T"]
|
||||
[#"3" #"A" #"B" #"C" #"D" #"F" #"G" #"I" #"J" #"K" #"N"]
|
||||
[#"7" #"P" #"Q" #"U" #"V" #"W" #"X" #"Y" #"Z" #"." #"/"]
|
||||
]
|
||||
|
||||
header: T/1 ;; digit labels for each column
|
||||
singles: T/2 ;; single-digit letters (H O L M E S R T)
|
||||
row3: T/3 ;; two-digit letters starting with 3
|
||||
row4: T/4 ;; two-digit letters starting with 7
|
||||
|
||||
encode: function [
|
||||
{Encode plaintext using the straddling checkerboard.
|
||||
Single-digit letters (row 2) encode to one digit;
|
||||
all others encode to two digits (row prefix + column digit).}
|
||||
plaintext [string!]
|
||||
][
|
||||
result: copy ""
|
||||
foreach ch plaintext [
|
||||
foreach row (next T) [ ;; skip header row
|
||||
if col: index? find row ch [
|
||||
repend result [row/1 header/:col] ;; row prefix ("" for singles) + column digit
|
||||
break
|
||||
]
|
||||
]
|
||||
]
|
||||
result
|
||||
]
|
||||
|
||||
decode: function [
|
||||
{Decode a straddling checkerboard ciphertext back to plaintext.
|
||||
Reads one digit at a time; if it matches a row prefix (3 or 7)
|
||||
the next digit selects the column in that row.}
|
||||
ciphertext [string!]
|
||||
][
|
||||
result: copy ""
|
||||
pos: 1
|
||||
while [pos <= length? ciphertext] [
|
||||
digit: ciphertext/(++ pos)
|
||||
append result case [
|
||||
digit == row3/1 [ ;; escape digit 3 -> read next for row3
|
||||
digit: ciphertext/(++ pos)
|
||||
letter: row3/(2 + digit - #"0")
|
||||
if letter == #"/" [++ pos]
|
||||
letter
|
||||
]
|
||||
digit == row4/1 [ ;; escape digit 7 -> read next for row4
|
||||
digit: ciphertext/(++ pos)
|
||||
row4/(2 + digit - #"0")
|
||||
]
|
||||
true [ ;; single-digit: look up in singles row
|
||||
singles/(2 + digit - #"0")
|
||||
]
|
||||
]
|
||||
]
|
||||
result
|
||||
]
|
||||
]
|
||||
|
||||
plaintext: "One night-it was on the twentieth of March, 1888-I was returning"
|
||||
encoded: encode 'straddle plaintext
|
||||
decoded: decode 'straddle encoded
|
||||
|
||||
print ["Original:" plaintext]
|
||||
print ["Encoded: " encoded ]
|
||||
print ["Decoded: " decoded ]
|
||||
|
|
@ -3,34 +3,34 @@ package require Tcl 8.6
|
|||
oo::class create StraddlingCheckerboardCypher {
|
||||
variable encmap decmap
|
||||
constructor table {
|
||||
# Sanity check the table
|
||||
foreach ch [lindex $table 0] i {"" 0 1 2 3 4 5 6 7 8 9} {
|
||||
if {$ch eq "" && $i ne "" && [lsearch -index 0 $table $i] < 1} {
|
||||
error "bad checkerboard table"
|
||||
}
|
||||
}
|
||||
# Synthesize the escaped number row
|
||||
foreach row $table {
|
||||
if {"/" ni $row} continue
|
||||
set pfx [lindex $row 0][expr {[lsearch -exact $row "/"]-1}]
|
||||
lappend table [list $pfx 0 1 2 3 4 5 6 7 8 9]
|
||||
break
|
||||
}
|
||||
# Build the actual per-character mapping
|
||||
foreach row $table {
|
||||
foreach ch [lrange $row 1 end] n {0 1 2 3 4 5 6 7 8 9} {
|
||||
if {$ch in {"" "/"}} continue; # Skip escape cases
|
||||
lappend encmap $ch [lindex $row 0]$n
|
||||
lappend decmap [lindex $row 0]$n $ch
|
||||
}
|
||||
}
|
||||
# Sanity check the table
|
||||
foreach ch [lindex $table 0] i {"" 0 1 2 3 4 5 6 7 8 9} {
|
||||
if {$ch eq "" && $i ne "" && [lsearch -index 0 $table $i] < 1} {
|
||||
error "bad checkerboard table"
|
||||
}
|
||||
}
|
||||
# Synthesize the escaped number row
|
||||
foreach row $table {
|
||||
if {"/" ni $row} continue
|
||||
set pfx [lindex $row 0][expr {[lsearch -exact $row "/"]-1}]
|
||||
lappend table [list $pfx 0 1 2 3 4 5 6 7 8 9]
|
||||
break
|
||||
}
|
||||
# Build the actual per-character mapping
|
||||
foreach row $table {
|
||||
foreach ch [lrange $row 1 end] n {0 1 2 3 4 5 6 7 8 9} {
|
||||
if {$ch in {"" "/"}} continue; # Skip escape cases
|
||||
lappend encmap $ch [lindex $row 0]$n
|
||||
lappend decmap [lindex $row 0]$n $ch
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# These methods just sanitize their input and apply the map
|
||||
method encode msg {
|
||||
string map $encmap [regsub -all {[^A-Z0-9.]} [string toupper $msg] ""]
|
||||
string map $encmap [regsub -all {[^A-Z0-9.]} [string toupper $msg] ""]
|
||||
}
|
||||
method decode msg {
|
||||
string map $decmap [regsub -all {[^0-9]} $msg ""]
|
||||
string map $decmap [regsub -all {[^0-9]} $msg ""]
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,75 @@
|
|||
const key = "
|
||||
8752390146
|
||||
ET AON RIS
|
||||
5BC/FGHJKLM
|
||||
0PQD.VWXYZU"
|
||||
|
||||
const pnt = "you have put on 7.5 pounds since I saw you."
|
||||
|
||||
fn main() {
|
||||
println(pnt)
|
||||
cnt := enc(key, pnt)
|
||||
println(cnt)
|
||||
println(dec(key, cnt))
|
||||
}
|
||||
|
||||
fn enc(bsg string, psg string) string {
|
||||
row := bsg.split("\n")[1..]
|
||||
r2d := row[2][..1]
|
||||
r3d := row[3][..1]
|
||||
mut enc := map[byte]string{}
|
||||
mut csg, mut dre, mut num := "", "", ""
|
||||
for col := 1; col <= 10; col++ {
|
||||
dre = row[0][col].ascii_str()
|
||||
enc[row[1][col]] = dre
|
||||
enc[row[2][col]] = r2d + dre
|
||||
enc[row[3][col]] = r3d + dre
|
||||
}
|
||||
num = enc[`/`]
|
||||
enc.delete(`/`)
|
||||
enc.delete(` `)
|
||||
for cal in psg.bytes() {
|
||||
if cal >= `0` && cal <= `9` { csg += num + cal.ascii_str() }
|
||||
else {
|
||||
mut ch := cal
|
||||
if ch >= `a` && ch <= `z` { ch -= `a` - `A` }
|
||||
csg += enc[ch] or { "" }
|
||||
}
|
||||
}
|
||||
return csg
|
||||
}
|
||||
|
||||
fn dec(bsg string, csg string) string {
|
||||
row := bsg.split("\n")[1..]
|
||||
r2d := row[2][0] - `0`
|
||||
r3d := row[3][0] - `0`
|
||||
mut cay := [10]int{}
|
||||
mut psg := ""
|
||||
mut dre, mut bre := rune(0), rune(0)
|
||||
mut inr, mut rnr := 0, 0
|
||||
for idx in 1 .. 11 {
|
||||
cay[int(row[0][idx]) - int(`0`)] = idx
|
||||
}
|
||||
for inr < csg.len {
|
||||
dre = csg[inr] - `0`
|
||||
rnr = 0
|
||||
match dre {
|
||||
r2d { rnr = 2 }
|
||||
r3d { rnr = 3 }
|
||||
else {
|
||||
psg += row[1][cay[int(dre)]].ascii_str()
|
||||
inr++
|
||||
continue
|
||||
}
|
||||
}
|
||||
inr++
|
||||
bre = row[rnr][cay[int(csg[inr] - `0`)]]
|
||||
if bre == `/` {
|
||||
inr++
|
||||
psg += csg[inr].ascii_str()
|
||||
}
|
||||
else { psg += bre.str() }
|
||||
inr++
|
||||
}
|
||||
return psg
|
||||
}
|
||||
|
|
@ -0,0 +1,88 @@
|
|||
' Straddling checkerboard - VBScript - 19/04/2019
|
||||
|
||||
Function encrypt(ByVal originalText, ByVal alphabet, blank1, blank2)
|
||||
Const notEscape = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ."
|
||||
Dim i, j, curChar, escChar, outText
|
||||
Dim cipher 'Hash table
|
||||
Set cipher = CreateObject("Scripting.Dictionary")
|
||||
'build cipher reference
|
||||
alphabet = UCase(alphabet) : j = 0
|
||||
For i = 1 To 28
|
||||
curChar = Mid(alphabet, i, 1)
|
||||
Select Case True
|
||||
Case i>= 1 And i<= 8
|
||||
If j = blank1 Or j = blank2 Then j = j + 1 'adjust for blank
|
||||
cipher.Add curChar, CStr(j)
|
||||
j = j + 1
|
||||
Case i>= 9 And i<=18
|
||||
cipher.Add curChar, CStr(blank1) & CStr(i - 9)
|
||||
Case i>=19 And i<=28
|
||||
cipher.Add curChar, CStr(blank2) & CStr(i - 19)
|
||||
End Select 'i
|
||||
If InStr(notEscape, curChar) = 0 Then
|
||||
escChar = curChar
|
||||
'Wscript.Echo "escChar=" & escChar & " cipher(escChar)=" & cipher(escChar)
|
||||
End If
|
||||
Next 'i
|
||||
For i = 0 To 9: cipher.Add CStr(i), cipher(escChar) & CStr(i): Next
|
||||
'encrypt each character
|
||||
originalText = UCase(originalText)
|
||||
For i = 1 To Len(originalText)
|
||||
outText = outText & cipher(Mid(originalText, i, 1))
|
||||
Next
|
||||
encrypt=outText
|
||||
End Function 'encrypt
|
||||
|
||||
Function decrypt(ByVal cipherText, ByVal alphabet, blank1, blank2)
|
||||
Const notEscape = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ."
|
||||
Dim i, j, curChar, escCipher, outText
|
||||
Dim cipher 'Hash table
|
||||
Set cipher = CreateObject("Scripting.Dictionary")
|
||||
'build decipher reference
|
||||
alphabet = UCase(alphabet) : j = 0
|
||||
For i = 1 To 28
|
||||
curChar = Mid(alphabet, i, 1)
|
||||
Select Case True
|
||||
Case i>= 1 And i<= 8
|
||||
If j = blank1 Or j = blank2 Then j = j + 1 'adjust for blank
|
||||
cipher.Add CStr(j),curChar
|
||||
j = j + 1
|
||||
Case i>= 9 And i<=18
|
||||
cipher.Add CStr(blank1) & CStr(i - 9), curChar
|
||||
Case i>=19 And i<=28
|
||||
cipher.Add CStr(blank2) & CStr(i - 19), curChar
|
||||
End Select 'i
|
||||
If InStr(notEscape, curChar) = 0 Then
|
||||
'the last element of cipher
|
||||
arrayKeys=cipher.keys
|
||||
escCipher = arrayKeys(cipher.count-1)
|
||||
'Wscript.Echo "escCipher=" & escCipher & " cipher(escCipher)=" & cipher(escCipher)
|
||||
End If
|
||||
Next 'i
|
||||
For i = 0 To 9: cipher.Add escCipher & CStr(i), CStr(i): Next
|
||||
'decrypt each character
|
||||
i = 1
|
||||
Do While i <= Len(cipherText)
|
||||
curChar = Mid(cipherText, i, 1)
|
||||
If curChar = CStr(blank1) Or curChar = CStr(blank2) Then
|
||||
curChar = Mid(cipherText, i, 2)
|
||||
If curChar = escCipher Then curChar = Mid(cipherText, i, 3)
|
||||
End If
|
||||
outText = outText & cipher(curChar)
|
||||
i = i + Len(curChar)
|
||||
Loop 'i
|
||||
decrypt=outText
|
||||
End Function 'decrypt
|
||||
|
||||
message = "One night-it was on the twentieth of March, 1888-I was returning"
|
||||
cipher = "HOLMESRTABCDFGIJKNPQUVWXYZ./"
|
||||
'3 7 <=8
|
||||
'HOL MES RT
|
||||
'ABCDFGIJKN
|
||||
'PQUVWXYZ./
|
||||
Buffer=Buffer & "Original: " & message & vbCrlf
|
||||
encoded = encrypt(message, cipher, 3, 7)
|
||||
Buffer=Buffer & "encoded: " & encoded & vbCrlf
|
||||
decoded = decrypt(encoded, cipher, 3, 7)
|
||||
Buffer=Buffer & "decoded: " & decoded & vbCrlf
|
||||
Wscript.Echo Buffer
|
||||
Loading…
Add table
Add a link
Reference in a new issue