Jump to content
View in the app

A better way to browse. Learn more.

FMForums.com

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

Puzzler: Rot13()

Featured Replies

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!

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"]

)

/* 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"]

)

Cipher solution breaks when numbers appear in the message. I think using something like "{{1}}" instead of "_1_" should fix it. Just to be safe, the same convention should be used in my Rot13() too.

  • Author

Good try...definitely doing it the hard way. I was looking for something that would work with upper and lower case letters and I'm not sure using obscure delimiters meets the criteria...unlikely, but someone might validly use {{1}} in a text.

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

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"]

)

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 ) ]

)

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 ) ) )

)

  • Author

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

)

Create an account or sign in to comment

Important Information

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

Account

Navigation

Search

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.