# code related to encryption, from Monday 4/8/08 class:

from random import randint

# generate random permutation:
def genpermutation(n):
    P = range(0,n)   # initial (identity) permutation
    i = 0
    while i<n:
        r = randint(0,n-1)
        P[i],P[r] = P[r],P[i]   # swap values of two array locations
        i = i+1
    return P
# genpermutation

# encryption via simple permutation.

# read permutation from file, returns string.
def readkey(fname):
        P = []
        fd = open(fname,"r")   # opens file for reading
        S = "dfs"  # some non-empty string
        while S!= "":    # S will be "" at end of file
                S = fd.readline()
                if S!="": P.append( int(S) )
        # ends while loop
        fd.close()
        return P
# readkey


# Function to convert between strings and arrays of chars
# For example, stringtoarray("abc") returns ["a","b","c"]
# and arraytostring(["a","b","c"]) returns "abc"
def stringtoarray(S):
        A = []
        i = 0
        while i<len(S):
                A.append(S[i])
                i += 1
        return A

def arraytostring(A):
        S = ""
        for c in A:  # "for each element/value c in array A"
                S = S+c
        return S
#arraytostring
#-------------------------------------------

# Check if an array is a permutation, O(n) algorithm:
def ispermutation(P):
    n = len(P)
    C = [0]*n  # array of n zeros, used to count
    answer = True
    i = 0
    while i<n and answer:
        if P[i]<0 or P[i]>=n: answer = False
        else: C[P[i]] += 1  # record
        i +=1
    # counting loop
    # now check if each value of C is 1:, 
    i =0
    while i<n and answer:
        if C[i]!=1: answer = False
        i +=1
    # check loop
    # Note the second while loop won't start if answer is already false
    return answer
# ispermutation



# This version of scramble assumes that the permutation P is of the same
# length as the string S:

def segmentscramble(S,P):
    E = [' ']*len(S)  # create array of right size, this will be the
                      # encrypted form
    i = 0
    while i<len(S):
        E[ P[i] ] = S[i]
        i += 1
    #while
    return arraytostring(E)  # turn array to a string before returning
#segmentscramble

# But now you have to consider situations where P is not as long as S.

    
