We are currently working on new rules for what content should and shouldn't be allowed on this website, and are looking for feedback! See Esolang:2026 topicality proposal to view and give feedback on the current draft.
User:Aadenboy/Miscellanium 2's cipher
Jump to navigation
Jump to search
The cipher used by Miscellanium 2 is based on two strings, where you require both strings and the deciphered string as it is currently known to decipher it. The format used is [ID]#[SUBID]; the names "ID" and "SUBID" are not relevant—all that is necessary is that ID defines the structure of the string and SUBID determines what is in it.
To encrypt with the cipher:
- Initialize two empty strings ID and SUBID.
- For each character in the string...
- If this is the first occurrence of this character...
- Append the character to SUBID.
- Insert the index of the character in SUBID to ID. This will also be the first instance of that number in ID.
- Otherwise...
- Take the substring of characters between the current character and the previous instance of it.
- Count how many unique characters there are in the substring.
- Add the count to ID. This will never exceed the current length of SUBID.
- If this is the first occurrence of this character...
hi im misc 1231421256#hi msc
To decrypt with the cipher:
- Initialize an empty result string.
- For each index in ID...
- If this is the first occurrence of this index...
- Add the character in SUBID with the same index to the result string.
- Otherwise...
- Pick the nth unique character starting from the end of the string, where n is the current index plus one.
- Add the character at that final position to the result string.
- If this is the first occurrence of this index...
For indexes greater than 9, they should be wrapped in parentheses, i.e 10 becomes (10).
Encryption implementations
Countable
/*
0 - 255 = Unique lookup (global)
256 - 511 = Unique lookup (local)
512 = Input/ID string end
513 = Input string length
514 = Current character
515 = SUBID string end
516 = SUBID string length
517 = Unique lookup index
The first table is for counting unique occurences everywhere.
The second table is for counting unique occurences between
two characters; the unique lookup key allows reuse of this
table by checking if each entry is equal to this value.
*/
512+525 // Input/ID string end
513+0 // Input string length
514+524 // Current character
515+525 // SUBID string end
516+0 // SUBID string length
517+524 // Unique lookup index
1*1< // Get input
2*∞<
a512@
*aa512<
512+1
513+1
515+1 // Just to save effort, we'll move the SUBID end alongside it
517+1 // Also this one
2&
>
1&
>
>
// We can reuse pointer 512 as it now points to the start of ID
515+a513 // ID will be the same length as the original string (ignoring digit length)
517+a513 517+a513 // SUBID will be either the same length as or shorter than the original string
0*a513< // Cipher the string
514+1
*aaa514< // Check if character has been seen before
0*1<
*∞<
aa514+1 // We can reuse the table entry as a second counter from its last instance
∞*1<
aaa514*1< // Check if we are at the current character
a514&
∞& // We are not, continue
>
0& // We are, stop checking
>
517+1
a517+256 a517+aaaa514 // Access the second lookup table
∞*1<
a514*1< // Check if the value is equal to the lookup key (current index in string)
0*1< aaa517& >
// Not equal
a512+1 // Increment the digit in ID by one
a514*1< // Set the value to equal the key
*∞<
aa517+1
aaa517&
>
>
∞&
>
// Equal
>
>
>
512+1 // Next character
0&
>
// Unique character
a515+aa514 515+1 // Append to SUBID
516+1 // Update length
a512+a516 512+1 // Length of SUBID corresponds to the same digit used for ID
aa514+a514 // The entry in the table will be the index of the character for easier use later
>
518+a517
519+a517
520+a517
521+a517
522+a517
523+a517
524+a517
∞*a513< // Print ID
514+1 // Move to next character in ID
*1<
0*1< 1*1< 2*1< 3*1< 4*1< 5*1< 6*1< 7*1< 8*1< 9*1< // Check if single digit
aa514&
// More than one digit
%40 // Left parenthesis
517+1 // Length
a517*1< *∞< a518& 518+1 > > 518+1 // Previous current value
a518+aa514 // Value to print
a517*1< *∞< a519& 519+1 > > 519+2 // Previous reversed value
a517*1< *∞< a520& 520+1 > > 520+aa518 520+aa518 520+1 // Current value
a517*1< *∞< a521& 521+1 > > 521+aa518 521+aa518 521+2 // Reversed value
a517*1< *∞< a522& 522+1 > > 522+aa518 522+aa518 522+4 // Equal flag
a517*1< *∞< a523& 523+1 > > 523+aa518 523+aa518 523+3 // Previous mod
a517*1< *∞< a524& 524+1 > > 524+aa518 524+aa518 524+4 // Pointer
// This is the same reverse-digit-then-print algorithm used by the A+B program.
0*1<
*∞<
1*1<
*aa518<
*aa518<
522+2
>
1&
>
0&
>
a517+1
a522+1
a523+9
10*1<
*∞<
*10<
*aa524<
10&
>
524+1
9*1<
0*1< 1*1< 2*1< 3*1< 4*1< 5*1< 6*1< 7*1< 8*1<
aa523&
> > > > > > > > >
a524+aa523 a524+1
>
524+1
523+2
>
a520+1
>
>
524+1
9*1<
0*1< 1*1< 2*1< 3*1< 4*1< 5*1< 6*1< 7*1< 8*1<
aa523&
> > > > > > > > >
a524+aa523 a524+1
>
*10<
a521+aa519
>
a521+aa524
522+5
523+5
524+4
a520*1<
*∞<
a519&
519+1
>
>
520+aa518 520+aa518 520+5
521+aa518 521+aa518 521+5
a519*1<
*∞<
a518&
518+1
>
>
519+1
>
>
a518+aa519
*aa517<
*aa518<
522+2
>
a522+1
a523+9
10*1<
*∞<
*10<
*aa524<
10&
>
524+1
9*1<
0*1< 1*1< 2*1< 3*1< 4*1< 5*1< 6*1< 7*1< 8*1<
aa523&
> > > > > > > > >
a524+aa523 a524+1
>
524+1
523+2
>
a520+1
>
>
524+1
9*1<
0*1< 1*1< 2*1< 3*1< 4*1< 5*1< 6*1< 7*1< 8*1<
aa523&
> > > > > > > > >
a524+aa523 a524+1
>
a524+48
%aa524
522+5
523+5
524+4
a520*1<
*∞<
a519&
519+1
>
>
520+aa518 520+aa518 520+5
521+aa518 521+aa518 521+5
a519*1<
*∞<
a518&
518+1
>
>
519+1
>
%41 // Right parenthesis
a523*1< *∞< a517& 517+1 > > // Move to new register
∞&
> > > > > > > > > >
// Single digit, simply transform and output
a514+48
%aa514
>
>
%35 // Hashtag
*a516< // Print SUBID
514+1 %aa514
>
Lua
o=io.read()u={}s=""print(o:gsub("()(.)",load'i,c=...if u[c]then z={}l=#({o:sub(0,i):match"(.)(.-)%1$"})[2]:gsub(".",load"c=...z[c]=(z[c]or 0)+1 return c:sub(z[c])")return l>9 and"("..l..")"or l end u[c]=#u s=s..c return #s>9 and"("..#s..")"or#s').."#"..s)
Decryption implementations
Lua
I,i=io.read():match"(.-)#(.+)"s=""n=1 p=1 repeat V=I:sub(p):match"^%b()"v=(V and V:sub(2,-2)or I:sub(p,p))+1 p=p+(V and#V or 1)if v>n then s=s..(" "..i):sub(v,v)n=n+1 else u=""z={}s:reverse():gsub(".",load'c=...z[c]=(z[c]or 0)+1 u=u..c:sub(z[c])')s=s..u:sub(v,v)end until#I<p print(s)