First, a few definitions: UniCh is the unicode value of the current character in the string. UniCu is the sum of the unicode value of the current character and the unicode value of every character preceding it. UniMx is the sum of all unicode values for all characters. StrLen is the number of characters in the input string. Constants are various primes with special focus on 48,271 and 2^31-1 (the 8th Mersenne prime).

Green bracketed text shows values and calculations for the example string "Sassafras." starting from the first character "S" (UniCh=83).

Let DirA = (StrLen + 389) times UniMx. [(10+389)*981=391,419]

Let DirB = mod(DirA, 701). [391,419 mod 701=261]

Let DirC = 48,271 times UniCu. [48,271*83=4,006,493]

Let DirD = mod(DirC + DirB, 2^31-1). The sum of DirC and DirB is way less than the modulus, so the modulo operation doesn't really matter here. [(4,006,493+261)=4,006,754; 4,006,754 mod 2,147,483,647=4,006,493]

Now we advance to the 2nd character, "a" (UniCh=97 so UniCu=180).

Let DirE = 48,271 times DirD. [48,271*4,006,493=193,410,022,334]

Let DirF = DirE + UniCu. [193,410,022,334+180=193,410,022,514]

Let DirG = mod(DirF, 2^31-1). [193,410,022,334 mod 2,147,483,647=136,494,284]

Let DirH = (DirG divided by 2^31-1) rounded to 16 decimal places if number of decimal places is greater than 16. [136,494,284/2,147,483,647=0.0635601040271856]

Let DirI = the last 7 digits of DirH. [0.0635601040271856 (last 7 digits)→ 0271856]

Let DirJ = the first 6 digits of DirI + UniCh. [0271856 (first 6 digits)→ 027185; 027185+97=27282]

Let DirK = mod(DirJ - 1, 6) + 1. [27282-1=27281; 27281 mod 6=5; 5+1=6]

Now we look up DirK's value on this table to get the direction:

6 = NW (northwest).

Why is this process so convoluted? I wanted to make the output hard to predict and ensure that relationships between different properties weren't obvious. Over many iterations the system got more and more complex. It isn't elegant, but I'm satisfied with how it behaves. The patterns it produces are what matter.