Jump to content

Puzzler: Rot13()


This topic is 5063 days old. Please don't post here. Open a new topic instead.

Recommended Posts

Here's a new puzzler....

Build a Rot13() custom function.

It should take a string and rotate each letter 13 places in the alphabet. Wiki Rot13 for more details. The function should only affect the letters on a string: A-Z and a-z.

If you don't have Advanced, do the above, but for single characters and wrap it in a Looping script.

Bonus points if you can do a string without a recursive custom function or looping. (I couldn't figure out how.)

Bonus points if you build it so any integer can be entered as a parameter in the function, creating a general Caesar cipher.

To keep it interesting, don't refer to any Filemaker resources outside of the FMP help files (ie no searching this site, or Dunning's custom function site, etc).

Tbbq yhpx!

Link to comment
Share on other sites

No recursive or looping.

It does require that the original text not contain any sequence that looks like "_nn_" where nn is a two digit number from 1 to 26. If there is likely to be such an odd string, you can change the intermediate format to something even more obscure.

/* Rot13(text) */

/* */

Substitute(

Substitute(

text;

["a";"_01_"]; ["b";"_02_"]; ["c";"_03_"]; ["d";"_04_"]; ["e";"_05_"];

["f";"_06_"]; ["g";"_07_"]; ["h";"_08_"]; ["i";"_09_"]; ["j";"_10_"];

["k";"_11_"]; ["l";"_12_"]; ["m";"_13_"]; ["n";"_14_"];["o";"_15_"];

["p";"_16_"]; ["q";"_17_"]; ["r";"_18_"]; ["s";"_19_"]; ["t";"_20_"];

["u";"_21_"]; ["v";"_22_"]; ["w";"_23_"]; ["x";"_24_"]; ["y";"_25_"];

["z";"_26_"]);

["_01_";"n"]; ["_02_";"o"]; ["_03_";"p"]; ["_04_";"q"]; ["_05_";"r"];

["_06_";"s"]; ["_07_";"t"]; ["_08_";"u"]; ["_09_";"v"]; ["_10_";"w"];

["_11_";"x"]; ["_12_";"y"]; ["_13_";"z"]; ["_14_";"a"];["_15_";"b"];

["_16_";"c"]; ["_17_";"d"]; ["_18_";"e"]; ["_19_";"f"]; ["_20_";"g"];

["_21_";"h"]; ["_22_";"i"]; ["_23_";"j"]; ["_24_";"k"]; ["_25_";"l"];

["_26_";"m"]

)

Link to comment
Share on other sites

/* CeasarCipher(text; offset) */

/* */

Substitute(

Substitute(

text;

["a";"_" & Mod(1 + offset;26) & "_"]; ["b";"_" & Mod(2 + offset;26) & "_"]; ["c";"_" & Mod(3 + offset;26) & "_"];

["d";"_" & Mod(4 + offset;26) & "_"]; ["e";"_" & Mod(5 + offset;26) & "_"]; ["f";"_" & Mod(6 + offset;26) & "_"];

["g";"_" & Mod(7 + offset;26) & "_"]; ["h";"_" & Mod(8 + offset;26) & "_"]; ["i";"_" & Mod(9 + offset;26) & "_"];

["j";"_" & Mod(10 + offset;26) & "_"]; ["k";"_" & Mod(11 + offset;26) & "_"]; ["l";"_" & Mod(12 + offset;26) & "_"];

["m";"_" & Mod(13 + offset;26) & "_"]; ["n";"_" & Mod(14 + offset;26) & "_"];["o";"_" & Mod(15 + offset;26) & "_"];

["p";"_" & Mod(16 + offset;26) & "_"]; ["q";"_" & Mod(17 + offset;26) & "_"]; ["r";"_" & Mod(18 + offset;26) & "_"];

["s";"_" & Mod(19 + offset;26) & "_"]; ["t";"_" & Mod(20 + offset;26) & "_"]; ["u";"_" & Mod(21 + offset;26) & "_"];

["v";"_" & Mod(22 + offset;26) & "_"]; ["w";"_" & Mod(23 + offset;26) & "_"]; ["x";"_" & Mod(24 + offset;26) & "_"];

["y";"_" & Mod(25 + offset;26) & "_"]; ["z";"_" & Mod(26 + offset;26) & "_"]);

["_1_";"a"]; ["_2_";"b"]; ["_3_";"c"]; ["_4_";"d"]; ["_5_";"e"];

["_6_";"f"]; ["_7_";"g"]; ["_8_";"h"]; ["_9_";"i"]; ["_10_";"j"];

["_11_";"k"]; ["_12_";"l"]; ["_13_";"m"]; ["_14_";"n"];["_15_";"o"];

["_16_";"p"]; ["_17_";"q"]; ["_18_";"r"]; ["_19_";"s"]; ["_20_";"t"];

["_21_";"u"]; ["_22_";"v"]; ["_23_";"w"]; ["_24_";"x"]; ["_25_";"y"];

["_0_";"z"]

)

Link to comment
Share on other sites

I was looking for something that would work with upper and lower case letters

The Rot13() could be augmented with all of the uppercase substitutions. Trivial but tedious.

The similarly coded CaesarCipher() would need additional substitutions for upper case. Using "{{1}}} for "a" and {^1^} for "A" should keep the cases separate.

For another submission here's a recursive function that is limited to FileMaker's 10,000 nesting for head recursion. Thus 10,000 char limit. Handles upper and lower case.

/* Caesar_cf(text; offset) */

/* recursive function */

/* */

Let(

[

n = Length(text);

x = Code(Left(text;1));

yuo = Mod(x - 96 + offset; 26);

ylo = Mod(x - 64 + offset; 26)

];

Case(

n = 0; "";

Case(

x > (97+25); Char(x); // > z

x < (65); Char(x); // < A

(x > 90) and (x < 97); Char(x); // Z < x < a

x ≥ 97; If(yuo; Char(yuo + 96); "z"); // a-z

If(ylo; Char(ylo + 64); "Z") // A-Z

) &

Caesar_cf(Right(text;n - 1); offset)

))

Edited by Guest
Link to comment
Share on other sites

For the sake of completeness, here is the brute force Substitute method handling upper and lowercase.

/* CeasarCipher(text; offset) */

/* */

Substitute(

Substitute(

text;

["a";"{{" & Mod(1 + offset;26) & "}}"]; ["b";"{{" & Mod(2 + offset;26) & "}}"]; ["c";"{{" & Mod(3 + offset;26) & "}}"];

["d";"{{" & Mod(4 + offset;26) & "}}"]; ["e";"{{" & Mod(5 + offset;26) & "}}"]; ["f";"{{" & Mod(6 + offset;26) & "}}"];

["g";"{{" & Mod(7 + offset;26) & "}}"]; ["h";"{{" & Mod(8 + offset;26) & "}}"]; ["i";"{{" & Mod(9 + offset;26) & "}}"];

["j";"{{" & Mod(10 + offset;26) & "}}"]; ["k";"{{" & Mod(11 + offset;26) & "}}"]; ["l";"{{" & Mod(12 + offset;26) & "}}"];

["m";"{{" & Mod(13 + offset;26) & "}}"]; ["n";"{{" & Mod(14 + offset;26) & "}}"];["o";"{{" & Mod(15 + offset;26) & "}}"];

["p";"{{" & Mod(16 + offset;26) & "}}"]; ["q";"{{" & Mod(17 + offset;26) & "}}"]; ["r";"{{" & Mod(18 + offset;26) & "}}"];

["s";"{{" & Mod(19 + offset;26) & "}}"]; ["t";"{{" & Mod(20 + offset;26) & "}}"]; ["u";"{{" & Mod(21 + offset;26) & "}}"];

["v";"{{" & Mod(22 + offset;26) & "}}"]; ["w";"{{" & Mod(23 + offset;26) & "}}"]; ["x";"{{" & Mod(24 + offset;26) & "}}"];

["y";"{{" & Mod(25 + offset;26) & "}}"]; ["z";"{{" & Mod(26 + offset;26) & "}}"];

["A";"{^" & Mod(1 + offset;26) & "^}"]; ["B";"{^" & Mod(2 + offset;26) & "^}"]; ["C";"{^" & Mod(3 + offset;26) & "^}"];

["D";"{^" & Mod(4 + offset;26) & "^}"]; ["E";"{^" & Mod(5 + offset;26) & "^}"]; ["F";"{^" & Mod(6 + offset;26) & "^}"];

["G";"{^" & Mod(7 + offset;26) & "^}"]; ["H";"{^" & Mod(8 + offset;26) & "^}"]; ["I";"{^" & Mod(9 + offset;26) & "^}"];

["J";"{^" & Mod(10 + offset;26) & "^}"]; ["K";"{^" & Mod(11 + offset;26) & "^}"]; ["L";"{^" & Mod(12 + offset;26) & "^}"];

["M";"{^" & Mod(13 + offset;26) & "^}"]; ["N";"{^" & Mod(14 + offset;26) & "^}"];["O";"{^" & Mod(15 + offset;26) & "^}"];

["P";"{^" & Mod(16 + offset;26) & "^}"]; ["Q";"{^" & Mod(17 + offset;26) & "^}"]; ["R";"{^" & Mod(18 + offset;26) & "^}"];

["S";"{^" & Mod(19 + offset;26) & "^}"]; ["T";"{^" & Mod(20 + offset;26) & "^}"]; ["U";"{^" & Mod(21 + offset;26) & "^}"];

["V";"{^" & Mod(22 + offset;26) & "^}"]; ["W";"{^" & Mod(23 + offset;26) & "^}"]; ["X";"{^" & Mod(24 + offset;26) & "^}"];

["Y";"{^" & Mod(25 + offset;26) & "^}"]; ["Z";"{^" & Mod(26 + offset;26) & "^}"]);

["{{1}}";"a"]; ["{{2}}";"b"]; ["{{3}}";"c"]; ["{{4}}";"d"]; ["{{5}}";"e"];

["{{6}}";"f"]; ["{{7}}";"g"]; ["{{8}}";"h"]; ["{{9}}";"i"]; ["{{10}}";"j"];

["{{11}}";"k"]; ["{{12}}";"l"]; ["{{13}}";"m"]; ["{{14}}";"n"];["{{15}}";"o"];

["{{16}}";"p"]; ["{{17}}";"q"]; ["{{18}}";"r"]; ["{{19}}";"s"]; ["{{20}}";"t"];

["{{21}}";"u"]; ["{{22}}";"v"]; ["{{23}}";"w"]; ["{{24}}";"x"]; ["{{25}}";"y"];

["{{0}}";"z"];

["{^1^}";"A"]; ["{^2^}";"B"]; ["{^3^}";"C"]; ["{^4^}";"D"]; ["{^5^}";"E"];

["{^6^}";"F"]; ["{^7^}";"G"]; ["{^8^}";"H"]; ["{^9^}";"I"]; ["{^10^}";"J"];

["{^11^}";"K"]; ["{^12^}";"L"]; ["{^13^}";"M"]; ["{^14^}";"N"];["{^15^}";"O"];

["{^16^}";"P"]; ["{^17^}";"Q"]; ["{^18^}";"R"]; ["{^19^}";"S"]; ["{^20^}";"T"];

["{^21^}";"U"]; ["{^22^}";"V"]; ["{^23^}";"W"]; ["{^24^}";"X"]; ["{^25^}";"Y"];

["{^0^}";"Z"]

)

Link to comment
Share on other sites

What about something along this line ?

( still in progress for simplify and complete )

Substitute ( Substitute ( text

; [ Char ( 65 ) ; Char ( 1000 ) ]

; [ Char ( 66 ) ; Char ( 1001 ) ]

; [ Char ( 67 ) ; Char ( 1002 ) ]

; [ Char ( 68 ) ; Char ( 1003 ) ]

; [ Char ( 69 ) ; Char ( 1004 ) ]

; [ Char ( 70 ) ; Char ( 1005 ) ]

; [ Char ( 71 ) ; Char ( 1006 ) ]

; [ Char ( 72 ) ; Char ( 1007 ) ]

; [ Char ( 73 ) ; Char ( 1008 ) ]

; [ Char ( 74 ) ; Char ( 1009 ) ]

; [ Char ( 75 ) ; Char ( 1010 ) ]

; [ Char ( 76 ) ; Char ( 1011 ) ]

; [ Char ( 77 ) ; Char ( 1012 ) ]

; [ Char ( 78 ) ; Char ( 1013 ) ]

; [ Char ( 79 ) ; Char ( 1014 ) ]

; [ Char ( 80 ) ; Char ( 1015 ) ]

; [ Char ( 81 ) ; Char ( 1016 ) ]

; [ Char ( 82 ) ; Char ( 1017 ) ]

; [ Char ( 83 ) ; Char ( 1018 ) ]

; [ Char ( 84 ) ; Char ( 1019 ) ]

; [ Char ( 85 ) ; Char ( 1020 ) ]

; [ Char ( 86 ) ; Char ( 1021 ) ]

; [ Char ( 87 ) ; Char ( 1022 ) ]

; [ Char ( 88 ) ; Char ( 1023 ) ]

; [ Char ( 89 ) ; Char ( 1024 ) ]

; [ Char ( 90 ) ; Char ( 1025 ) ]

)

; [ Char ( 1000 ) ; Char ( 78 ) ]

; [ Char ( 1001 ) ; Char ( 79 ) ]

; [ Char ( 1002 ) ; Char ( 80 ) ]

; [ Char ( 1003 ) ; Char ( 81 ) ]

; [ Char ( 1004 ) ; Char ( 82 ) ]

; [ Char ( 1005 ) ; Char ( 83 ) ]

; [ Char ( 1006 ) ; Char ( 84 ) ]

; [ Char ( 1007 ) ; Char ( 85 ) ]

; [ Char ( 1008 ) ; Char ( 86 ) ]

; [ Char ( 1009 ) ; Char ( 87 ) ]

; [ Char ( 1010 ) ; Char ( 88 ) ]

; [ Char ( 1011 ) ; Char ( 89 ) ]

; [ Char ( 1012 ) ; Char ( 90 ) ]

; [ Char ( 1013 ) ; Char ( 65 ) ]

; [ Char ( 1014 ) ; Char ( 66 ) ]

; [ Char ( 1015 ) ; Char ( 67 ) ]

; [ Char ( 1016 ) ; Char ( 68 ) ]

; [ Char ( 1017 ) ; Char ( 69 ) ]

; [ Char ( 1018 ) ; Char ( 70 ) ]

; [ Char ( 1019 ) ; Char ( 71 ) ]

; [ Char ( 1020 ) ; Char ( 72 ) ]

; [ Char ( 1021 ) ; Char ( 73 ) ]

; [ Char ( 1022 ) ; Char ( 74 ) ]

; [ Char ( 1023 ) ; Char ( 75 ) ]

; [ Char ( 1024 ) ; Char ( 76 ) ]

; [ Char ( 1025 ) ; Char ( 77 ) ]

)

Link to comment
Share on other sites

My vote is for a recursive CF.

/*

Rot13 ( text )

*/

Let(

c = Code ( Left ( text ;  1 ) ) ;

Case ( c ;

Case(

c > 64 and c <  91 ; Char ( Mod ( c - 52 ; 26 ) + 65 ) ;

c > 96 and c < 123 ; Char ( Mod ( c - 84 ; 26 ) + 97 ) ;

Char ( c )

) & Rot13 ( Right ( text ; Length ( text ) - 1 ) ) )

)

Link to comment
Share on other sites

Here's mine:

Let([

var = Mod(var;26);

thisChar = Left(text;1);

num = Code(thisChar);

type = Case( (num ≥ 65 and num ≤ 90) ; "upper"; num ≥ 97 and num ≤ 122; "lower" ; "non") ;

rotted = num + Case( type = "non"; 0; var);

adjust = Case( type = "upper" and rotted > 90; rotted -26; type = "lower" and rotted > 122; rotted - 26; rotted);

newChar = Char(adjust);

newText = Right(text; Length(text)-1);

result = newChar & Case( Length(newText); Rot(newText; var))

];

result

)

Link to comment
Share on other sites

This topic is 5063 days old. Please don't post here. Open a new topic instead.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.