ROT13
February 20, 2009
This code is available at http://programmingpraxis.codepad.org/xSLxDTmO:
(define (rot13 s)
(define (char-plus c n)
(integer->char (+ n (char->integer c))))
(define (rot c)
(cond ((char<=? #\a c #\m) (char-plus c 13))
((char<=? #\n c #\z) (char-plus c -13))
((char<=? #\A c #\M) (char-plus c 13))
((char<=? #\N c #\Z) (char-plus c -13))
(else c)))
(list->string (map rot (string->list s))))
> (rot13 "Cebtenzzvat Cenkvf vf sha!")
"Programming Praxis is fun!"
This is a rather trivial exercise for Oracle’s PL/SQL since it has a TRANSLATE function. This function translates each character in a given string using “from” and “to” positional strings, passed as parameters (along with the target string, of course). Each character in the target string found in the “from” string is replaced by the corresponding character in the “to” string. Quite handy, especially for doing ROT13. But as you can see, I only included a couple of special characters in the translation strings, so my first implementation was rather limited:
Rather than adding all the non-alphabetics I could type, I decided to write my own simple translation logic to handle any ASCII character:
function rot13(parm_str in varchar2) return varchar2 is
j pls_integer ;
parm_ret varchar2(1000) := null ;
begin
for i in 1..length(parm_str)
loop
j := ascii(substr(parm_str,i,1)) ;
case
when j>=65 and j<=90 /* A-Z */ then j:=j-13 ; if j<65 then j:=j+26; end if ; when j>=97 and j<=122 /* a-z */ then j:=j-13; if j<97 then j:=j+26; end if ; else null ; end case ; parm_ret := parm_ret||chr(j); end loop ; return parm_ret ; end rot13 ; [/sourcecode] Simple, but it works.
Not too hard in perl:
y/A-Za-z/N-ZA-Mn-za-m/;
import Maybe (fromMaybe)
import Data.List (find)
genTab :: Int -> [(Char, Char)]
genTab rot = zip (['a'..'z'] ++ ['A'..'Z']) (take 26 (drop rot (cycle ['a'..'z'])) ++
take 26 (drop rot (cycle ['A'..'Z'])))
{- apply the cipher function to the string. It substitutes values obtained from the
lookup table, generated by the function genTab -}
rotFunc :: Int -> String -> String
rotFunc rot str = map cipher str
where cipher c = (snd (fromMaybe (c,c) (find (\ x -> (fst x) == c) (genTab rot))))
rot13 :: String -> String
rot13 = rotFunc 13
Alternative Haskell approach:
My OCaml version.
let rot13 s =
let rotate c =
let aux i = char_of_int ( i + (int_of_char c – i + 13) mod 26) in
match c with
| ‘A’..’Z’ -> aux 65
| ‘a’..’z’ -> aux 97
| _ -> c
in
for i = 0 to String.length s – 1 do s.[i] <- rotate s.[i] done let _ = let s = "Cebtenzzvat Cenkvf vf sha!" in rot13 s; print_endline s [/sourcecode]
Very simple python solution, but makes everything lowercase
def rotate(ox, base):
return chr(base + ((ox – base) + 13) % 26)
def handle(x):
ox = ord(x)
if ord(“a”) <= ox and ox <= ord("z"): return rotate(ox, ord("a")) elif ord("A") <= ox and ox <= ord("Z"): return rotate(ox, ord("A")) else: return x def rot13(input): return "".join(map(handle, input)) [/sourcecode] >>> rot13("Cebtenzzvat Cenkvf vf sha!") 'Programming Praxis is fun!'
A solution in SML.
(* ROT13 cipher *)
(* see: http://programmingpraxis.com/2009/02/20/rot13/ *)
fun rot13 (str : string) : string =
let
fun wrapTo (ch : char, top : char) : char =
let
val next = Char.ord ch + 13
in
if next > Char.ord top then
Char.chr (next – 26)
else
Char.chr (next)
end
fun rotChar (ch : char) : char =
if ch >= #”a” andalso ch <= #”z” then
wrapTo (ch, #”z”)
else if ch >= #”A” andalso ch <= #”z” then
wrapTo (ch, #”Z”)
else
ch
in
String.map rotChar str
end
Thought this would be nice in ruby …
Adding rot13 to the String class makes it available for all Strings. Kind of a nice feature.
Python – a more functional & less readable approach:
[…] this ProgrammingPraxis challenge we have to build a simple Caesar Cipher variant called rot13 […]
This is probably much longer than it has to be, but here is my solution in python:
alpha = {
‘a’:’n’,
‘b’:’o’,
‘c’:’p’,
‘d’:’q’,
‘e’:’r’,
‘f’:’s’,
‘g’:’t’,
‘h’:’u’,
‘i’:’v’,
‘j’:’w’,
‘k’:’x’,
‘l’:’y’,
‘m’:’z’,
‘n’:’a’,
‘o’:’b’,
‘p’:’c’,
‘q’:’d’,
‘r’:’e’,
‘s’:’f’,
‘t’:’g’,
‘u’:’h’,
‘v’:’i’,
‘w’:’j’,
‘x’:’k’,
‘y’:’l’,
‘z’:’m’}
txt = input(‘Text to cypher with rot13: ‘)
txtlst = list(txt)
count = 0
while count < len(txtlst):
let = txtlst[count]
txtlst[count] = alpha[let]
count+=1
rotd = "".join(txtlst)
print(txt+" becomes "+rotd)
Tcl
#
# Gives a version that doesn’t require any additional procedures, and rotates by any amount (specified by an optional second argument,
# defaults to 13 of course) — And supports negative rotation amounts
#
proc rot {text {amount 13}} {
if {abs($amount) > 25} {
set amount [expr {$amount % 26}]
}
set alphabet “ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz”
set res “”
set length [string length $text]
set find_command [expr {$amount > 0 ? “first” : “last”}]
for {set index 0} {$index < $length} {incr index} {
set char [string index $text $index]
set pos [string $find_command $char $alphabet]
append res [expr {$pos == -1 ? $char : [string index $alphabet [expr {$pos + $amount}]]}]
}
return $res
}
#!/usr/bin/env python
def ROT13(plain):
cypher = ”
for char in plain:
if char.isalpha():
raw = ord(char)
if raw in range(97,110) or raw in range(65,78):
char = chr(raw+13)
else:
char = chr(raw-13)
cypher = cypher + char
return cypher
if __name__ == ‘__main__’:
print ROT13(‘Cebtenzzvat Cenkvf vf sha!’)
And here is my example in Python:
My version in Haskell:
GoLang
golang
https://github.com/ftt/programming-praxis/blob/master/20090220-rot13/rot13.py
ugly ruby code (http://codepad.org/zldHFsDm)
Java solution:
Python. Not sure about efficiency, but I got to play with strings.
import string
def rot13(input):
shift = 13
lst = list(input)
c = 0
while c = 97 and i = 65 and i <= 90 : # [A-Z]
lst[c] = (chr(( i-65-shift)%26 + 65))
c += 1
return ''.join(map(''.join,lst))
print(rot13('The butler did it!')) # Gur ohgyre qvq vg!
Python, also attempting to format correctly… sorry for double post.
in coffeescript:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
gistfile1.txt
hosted with ❤ by GitHub
Reblogged this on graveborn and commented:
The following is the source code to my solution to the 6th problem – “ROT13: A simple Caesar-shift cipher” – of Programming Praxis, and my first program for the Amstrad Plus.
I don’t know if the additional features of the Amstrad Plus are accessible through CP/M and Pascal, but my goal when programming the following solution was merely to gain a little familiarity with using the Amstrad Plus, eg. a familiarity with editing, saving, and loading text files, and erasing files.
[…] Reblogged from Programming Praxis: […]
[…] following is the source code to my solution to the 6th problem – “ROT13: A simple Caesar-shift cipher” – of Programming Praxis, and my first program for the […]
Sorry for double post i’m trying to highlight my code correctly
My C++ version:
My C++ version:
#include <iostream>
#include <string>
#include <cctype>
using namespace std;
void getUserInput(string &strUserInput)
{
cout<< "Enter your text: " << endl;
getline(cin, strUserInput);
}
void ROT13(string &strUserInput, string &strResult)
{
for (auto it = strUserInput.begin(); it != strUserInput.end(); ++it)
{
if (isspace(*it) || ispunct(*it))
strResult += *it;
else
{
if (isupper(*it))
{
if (*it + 13 <= ‘Z’)
strResult += (*it + 13);
else
strResult += (*it – 13);
}
else
{
if (*it + 13 <= ‘z’)
strResult += (*it + 13);
else
strResult += (*it – 13);
}
}
}
}
int main()
{
string strUserInput, strResult;
getUserInput(strUserInput);
ROT13(strUserInput, strResult);
cout<< "The result text is: " << strResult << endl;
cin.get();
return 0;
}
My small version in C++ :
#include
std::string Rot13(std::string Input)
{
int i;
for(i=0; i = 65 && Input[i] = 97 && Input[i] = 78 && Input[i] = 110 && Input[i] <= 122))
Input[i] -= 13;
}
return Input;
}
Learning to Scala! A copy off of my worksheet:
#——————————————————————————-
# Name: Ceaser Cipher
# Author: Mrinal Wahal
# Created: 19/08/2014
# Copyright: (c) Mrinal 2014
#——————————————————————————-
alphas = {}
bets = ‘abcdefghijklmnopqrstuvwxyz’
string = raw_input(“Enter Your String Here – “)
print “NOTE – Value 0 Will Assign Default Rotation of 13 Places.”
rotation = input(“Rotation Should Take Place By – “)
num = 0
for letter in bets:
num += 1
alphas[letter]=num
def encrypt(string,rotation):
encrypted = “”
for let in string:
if rotation == 0:
rotation = 13
newvalue = alphas[let] + rotation
if newvalue > 26:
newvalue -= 26
for key in alphas.iterkeys():
if alphas[key] == newvalue:
print key,
encrypted += key
return encrypted
print “The Encrypted String is :”
en = encrypt(string,rotation)
def decrypt(dstring,drotation):
for dlet in str(dstring):
if drotation == 0:
drotation = 13
dnewvalue = alphas[dlet] – drotation
if dnewvalue < 0:
dnewvalue += 26
for dkey in alphas.iterkeys():
if alphas[dkey] == dnewvalue:
print dkey,
print "\nThe Decrypted String is :"
decrypt(en,rotation)
I think using C++11/14 makes for a very concise solution.
#include “Praxis006.hpp”
#include
#include
#include
// We can take advantage of RVO since rot13 is reversible
std::string rot13(std::string& line) {
std::transform(line.begin(), line.end(), line.begin(), [](char c) -> char {
if(not isalpha(c))
return c;
const char pivot = isupper(c) ? ‘A’ : ‘a’;
return (c – pivot + 13) % 26 + pivot;
});
return line;
}
void Praxis006() {
std::fstream f(“Rot13.txt”);
std::string line;
if(f.is_open()) {
std::getline(f, line);
rot13(line);
std::cout << line << std::endl;
}
}
February 20th, 2009.c:
The meaning of
“Cebtenzzvat Cenkvf vf sha!”
is“Programming Praxis is fun!”
The solution is known to run on an Apple Power Mac G4 (AGP Graphics) (450MHz processor, 1GB memory) on both Mac OS 9.2.2 (International English) (the solution interpreted using Leonardo IDE 3.4.1 and compiled using Metrowerks CodeWarrior IDE 2.1 (Discover Programming Edition)) and Mac OS X 10.4.11 (the solution compiled using the command line:
gcc seal_bool.h February\ 20th\,\ 2009.c -o February\ 20th\,\ 2009
).(I’m just trying to solve the problems posed by this ‘site whilst I try to get a job; I’m well-aware that my solutions are far from the best – but, in my defence, I don’t have any traditional qualifications in computer science :/ )
Ps. It’s a little early, but merry Christmas, and thank you for running this ‘site!
Answer:
Programming Praxis is fun!