Letters to numbers | Numbers to letters | Preparing RSA keys | Some bitstream routines | Computing the GAG number |
A2N:=proc(input) local zorch,L,ss,j_,base,num; zorch:=0; L:=length(input); base:=1;num:=0; for j_ from 1 to L do ss:=substring(input,L-j_+1..L-j_+1); if ss='a' then num:=01 elif ss='b' then num:=02 elif ss='c' then num:=03 elif ss='d' then num:=04 elif ss='e' then num:=05 elif ss='f' then num:=06 elif ss='g' then num:=07 elif ss='h' then num:=08 elif ss='i' then num:=09 elif ss='j' then num:=10 elif ss='k' then num:=11 elif ss='l' then num:=12 elif ss='m' then num:=13 elif ss='n' then num:=14 elif ss='o' then num:=15 elif ss='p' then num:=16 elif ss='q' then num:=17 elif ss='r' then num:=18 elif ss='s' then num:=19 elif ss='t' then num:=20 elif ss='u' then num:=21 elif ss='v' then num:=22 elif ss='w' then num:=23 elif ss='x' then num:=24 elif ss='y' then num:=25 elif ss='z' then num:=26 fi; zorch:=num*base+zorch; base:=100*base od; RETURN(zorch); end;And here is how it could be used:
>A2N(zax); 260124 >A2N(azx); 12624Note that when the first letter is "a", the output number should begin "01" but leading 0's aren't printed: an amateur's routine.
N2A:=proc(input) local cut_down, ss,zorch,alph; alph:=`abcdefghijklmnopqrstuvwxyz`; cut_down:=input;zorch:=``; while(type(cut_down,positive)) do ss:=irem(cut_down,100); cut_down:=(cut_down-ss)/100; zorch:=cat(substring(alph,ss..ss),zorch) od; RETURN(zorch); end;Below are some simple uses of this routine. Note the spurious answers for bad input -- I've definitely not written "bulletproof" computer code!
>N2A(260124); zax >N2A(12624); azx >N2A(37); >N2A(237); b >N2A(9); i
ES:=proc(base,power,modulus) local A,B,C; A:=1; B:=power;C:=base; while type(B,positive) do if type(B,odd) then A:=A*C mod modulus; B:=B-1; fi; B:=B/2; C:=C^2 mod modulus od; RETURN(A); end;Uses of ES are documented on the RSA web page.
RSA:=proc(n) local P,Q,frog,T,R,S,toad,zebra; P:=3;Q:=5; while(type(2*n-length(P*Q),positive) and P<>Q) do frog:=rand(10^(n-1)..10^n-1); P:=nextprime(frog()); Q:=nextprime(frog()) od; T:=(P-1)*(Q-1); toad:=rand(10^iquo(2*n,4)..10^(3*iquo(2*n,4))); R:=T; while(igcd(T,R)>1) do R:=toad(); zebra:=msolve(R*S=1,T) od;assign(zebra); RETURN(P,Q,P*Q,R,S); end;And here is a use of this routine:
>RSA(15); 481321110693277, 397474256143567, 191312750439005747675813699059, 305613921751630036805, 163151755562420097036265148189The last two numbers are the encryption and decryption exponents.
Please type readlib(unassign); before using the routine below.
keys:=proc(n,m,P,Q) local R,S,T,count,toad,zebra;count:=m; T:=(P-1)*(Q-1); toad:=rand(10^iquo(2*n,4)..10^(3*iquo(2*n,4))); while (type(count,positive)) do R:=T; while(igcd(T,R)>1) do R:=toad(); zebra:=msolve(R*S=1,T) od; assign(zebra); print(R,S);unassign('S'); count:=count-1 od; end;Here's a use of keys. Maple verifies that two numbers are prime using the first two instructions.
>ifactor(311); (311) >ifactor(503); (503) >keys(4,3,311,503); 98333, 40177 693739, 9799 533593, 2297 0Three e/d pairs are found. The first parameter (4, above) asks that the first number be (uniformly) (pseudo-)randomly chosen between .5n and 1.5n digits long -- in this case, between 2 and 6 digits long. Of course, there isn't much chance that the number will be 2 or 3 digits long!
fiver:=proc(tiger) local m,empty,zorch,v,j; zorch:=``; m:=iquo(length(tiger),5,v); if type(v,positive) then m:=m+1 fi; empty:=` `; for j to m do zorch:=cat(zorch,substring(tiger,(j-1)*5+1 .. j*5),empty) od; RETURN(zorch); end;Here is an example. Note that a string must be specified with ` at the beginning and the end.
>fiver(`010001111100`); 01000 11111 00 >fiver(000111111); Error, (in fiver) string or symbol expected for substring
xor:=proc(frog,toad) local m,zorch,j,zero,one,f,t; m:=min(length(frog),length(toad)); zorch:=``;zero:=`0`;one:=`1`; for j from 1 to m do f:=substring(frog,j .. j); t:=substring(toad,j .. j); if f=t then zorch:=cat(zorch,zero) else zorch:=cat(zorch,one) fi; od; RETURN(zorch); end;Here is an example of how it can be used:
>xor(`01010101`,`111000`); 101101Note that the output is a bitstream whose length is the minimum of the lengths of the two bitstreams to be xored.
>vocab:= [`000000`,3,`11111`,2]; vocab := [000000, 3, 11111, 2]and then use the following:
lang:=proc(vocab,N) local tt,k,v,total,rn,zorch,test,test_1,test_2; v:=nops(vocab); zorch:=``; total:=sum('vocab[2*k]',k=1..iquo(v,2)); rn:=rand(1..total); if v=2 then while type(N-length(zorch),positive) do zorch:=cat(zorch,vocab[1]); od else test:=seq([vocab[2*test_1-1],sum('vocab[2*test_2]',test_2=1..test_1)],test_1=1..iquo(v,2)); while type(N-length(zorch),positive) do tt:=rn(); if tt<=test[1][2] then zorch:=cat(zorch,test[1][1]) else v:=1; while type(tt-test[v][2],positive) do v:=v+1 od; zorch:=cat(zorch,test[v][1]); fi; od; fi; RETURN(zorch); end;We can demonstrate its use (twice!) as follows:
>lang(vocab,30); 000000111110000001111100000011111 >fiver(%); 00000 01111 10000 00111 11000 00011 111 >lang(vocab,30); 0000001111100000000000000000011111 >fiver(%); 00000 01111 10000 00000 00000 00001 1111Since lang uses the Maple rand function, its output will likely be different each time it is invoked, even with the same parameters. Note that lang is requesting in each case a bitstream which is 30 bits long. The outputs (if A is 000000 and B is 11111) are the bitstreams corresponding to ABABAB and ABAAAB. There are 7 A's and 5 B's in total,so that A's are somewhat more common. But note that the length of the first output is 33 bits and the lenght of the second output is 34 bits. lang stops when the sequence of A's and B's it creates is at least 30 bits long. lang then prints the entire sequence of 0's and 1's implied by the letters.
vowel:=proc(input) local zorch, L, j_, ss; zorch:=0; L:=length(input); for j_ from 1 to L do ss:=substring(input,L-j_+1..L-j_+1); if ss='a' then zorch:=zorch+1 elif ss='e' then zorch:=zorch+1 elif ss='i' then zorch:=zorch+1 elif ss='o' then zorch:=zorch+1 elif ss='u' then zorch:=zorch+1 fi; od; RETURN(zorch); end;Its use is clear:
>vowel(frog); 1
space:=proc(input) local zorch, L, j_, ss; zorch:=0; L:=length(input); for j_ from 1 to L do ss:=substring(input,L-j_+1..L-j_+1); if ss=` ` then zorch:=zorch+1 fi; od; RETURN(zorch); end;Note that here a phrase must be delimited by `.
>space(`frog jumps`); 1 >space(frog jumps); missing operator or `;`
GAG:=proc(input) local vo,sp,L,cons; vo:=vowel(input);sp:=space(input);L:=length(input); cons:=L-vo-sp; RETURN(7*vo-3*cons+sp^2 mod 17); end;Here is a use of GAG taken from the hoemwork assignment:
>GAG(`We jointly and equally own the gravel pit at Loon Lake.`); 16 >GAG(`Ted has one third interest in the Loon Lake gravel pit.`); 16