---第一
任意给定两个素数p和q,p!= q,记 N = p * q ,构造Zn*,
问(编程解决):
1、是否每个元素都有inverse?是否成群? 2、这个集合有多少元素?
判断是否为素数
def isprime():
count =1
while (count):
n = int(input("输入一个质数:"))
for i in range(2, n):
if n % i == 0:
print(" %d 这不是一个质数!" % n)
break
else:
return n
生成一个与N互素的列表
def CommonFactor(a,b):
if a
t = a
a = b
b = t
while(a%b):
t = b
b = a % b
a = t
return b
判断是否存在逆元
def is_inverse(list,n):
mark=1
for i in range(0,len(list)):
count=1
for j in range(0,len(list)):
if((list[i]*list[j])%n==1):
count =0
print("%s存在逆元%s"%(list[i],list[j]),end=" ")
if count:
print("%s不存在逆元"%(list[i]),end=" ")
mark=0
print()
if(mark):
print("任何元素都有逆元")
return mark
判断运算是否封闭
def is_closed(list,n):
mark=1
for i in range(0, len(list)):
for j in range(0, len(list)):
count=0
for k in range(0, len(list)):
if((list[i]*list[j])%n == list[k]):
count=1
num=list[k]
if count:
print("%s*%s封闭值为%s"%(list[i],list[j],num))
else:
print("%s*%s不封闭"%(list[i],list[j]))
mark=0
return mark
主函数
def main():
p=isprime()
count=1
while(count):
q=isprime()
if not q==p:
count=0
else:
print("与第一个质数相同,请重新输入")
n=p*q
list=[]
for i in range(1,n):
k=CommonFactor(i,n)
if k==1:
list.append(i)
for i in range(0,len(list)):
print(list[i],end=" ")
print()
a=is_inverse(list,n)
b=is_closed(list,n)
if a==1 and b==1:
print("任意元素都有逆元且运算封闭,成群")
print("群元素有%s个"%(len(list)))
elif a==0:
print("存在元素没有逆元,不成群")
elif b==0:
print("运算不封闭,不成群")
main()
--- 第二
写一个程序,实现AES的S-box的构造。
importsys, hashlib, string, getpass
fromcopyimportcopy
fromrandomimportrandint
#The actual Rijndael specification includes variable block size, but
#AES uses a fixed block size of 16 bytes (128 bits)
#Additionally, AES allows for a variable key size, though this implementation
#of AES uses only 256-bit cipher keys (AES-256)
sbox=[
0x63,0x7c,0x77,0x7b,0xf2,0x6b,0x6f,0xc5,0x30,0x01,0x67,0x2b,0xfe,0xd7,0xab,0x76,
0xca,0x82,0xc9,0x7d,0xfa,0x59,0x47,0xf0,0xad,0xd4,0xa2,0xaf,0x9c,0xa4,0x72,0xc0,
0xb7,0xfd,0x93,0x26,0x36,0x3f,0xf7,0xcc,0x34,0xa5,0xe5,0xf1,0x71,0xd8,0x31,0x15,
0x04,0xc7,0x23,0xc3,0x18,0x96,0x05,0x9a,0x07,0x12,0x80,0xe2,0xeb,0x27,0xb2,0x75,
0x09,0x83,0x2c,0x1a,0x1b,0x6e,0x5a,0xa0,0x52,0x3b,0xd6,0xb3,0x29,0xe3,0x2f,0x84,
0x53,0xd1,0x00,0xed,0x20,0xfc,0xb1,0x5b,0x6a,0xcb,0xbe,0x39,0x4a,0x4c,0x58,0xcf,
0xd0,0xef,0xaa,0xfb,0x43,0x4d,0x33,0x85,0x45,0xf9,0x02,0x7f,0x50,0x3c,0x9f,0xa8,
0x51,0xa3,0x40,0x8f,0x92,0x9d,0x38,0xf5,0xbc,0xb6,0xda,0x21,0x10,0xff,0xf3,0xd2,
0xcd,0x0c,0x13,0xec,0x5f,0x97,0x44,0x17,0xc4,0xa7,0x7e,0x3d,0x64,0x5d,0x19,0x73,
0x60,0x81,0x4f,0xdc,0x22,0x2a,0x90,0x88,0x46,0xee,0xb8,0x14,0xde,0x5e,0x0b,0xdb,
0xe0,0x32,0x3a,0x0a,0x49,0x06,0x24,0x5c,0xc2,0xd3,0xac,0x62,0x91,0x95,0xe4,0x79,
0xe7,0xc8,0x37,0x6d,0x8d,0xd5,0x4e,0xa9,0x6c,0x56,0xf4,0xea,0x65,0x7a,0xae,0x08,
0xba,0x78,0x25,0x2e,0x1c,0xa6,0xb4,0xc6,0xe8,0xdd,0x74,0x1f,0x4b,0xbd,0x8b,0x8a,
0x70,0x3e,0xb5,0x66,0x48,0x03,0xf6,0x0e,0x61,0x35,0x57,0xb9,0x86,0xc1,0x1d,0x9e,
0xe1,0xf8,0x98,0x11,0x69,0xd9,0x8e,0x94,0x9b,0x1e,0x87,0xe9,0xce,0x55,0x28,0xdf,
0x8c,0xa1,0x89,0x0d,0xbf,0xe6,0x42,0x68,0x41,0x99,0x2d,0x0f,0xb0,0x54,0xbb,0x16
]
sboxInv=[
0x52,0x09,0x6a,0xd5,0x30,0x36,0xa5,0x38,0xbf,0x40,0xa3,0x9e,0x81,0xf3,0xd7,0xfb,
0x7c,0xe3,0x39,0x82,0x9b,0x2f,0xff,0x87,0x34,0x8e,0x43,0x44,0xc4,0xde,0xe9,0xcb,
0x54,0x7b,0x94,0x32,0xa6,0xc2,0x23,0x3d,0xee,0x4c,0x95,0x0b,0x42,0xfa,0xc3,0x4e,
0x08,0x2e,0xa1,0x66,0x28,0xd9,0x24,0xb2,0x76,0x5b,0xa2,0x49,0x6d,0x8b,0xd1,0x25,
0x72,0xf8,0xf6,0x64,0x86,0x68,0x98,0x16,0xd4,0xa4,0x5c,0xcc,0x5d,0x65,0xb6,0x92,
0x6c,0x70,0x48,0x50,0xfd,0xed,0xb9,0xda,0x5e,0x15,0x46,0x57,0xa7,0x8d,0x9d,0x84,
0x90,0xd8,0xab,0x00,0x8c,0xbc,0xd3,0x0a,0xf7,0xe4,0x58,0x05,0xb8,0xb3,0x45,0x06,
0xd0,0x2c,0x1e,0x8f,0xca,0x3f,0x0f,0x02,0xc1,0xaf,0xbd,0x03,0x01,0x13,0x8a,0x6b,
0x3a,0x91,0x11,0x41,0x4f,0x67,0xdc,0xea,0x97,0xf2,0xcf,0xce,0xf0,0xb4,0xe6,0x73,
0x96,0xac,0x74,0x22,0xe7,0xad,0x35,0x85,0xe2,0xf9,0x37,0xe8,0x1c,0x75,0xdf,0x6e,
0x47,0xf1,0x1a,0x71,0x1d,0x29,0xc5,0x89,0x6f,0xb7,0x62,0x0e,0xaa,0x18,0xbe,0x1b,
0xfc,0x56,0x3e,0x4b,0xc6,0xd2,0x79,0x20,0x9a,0xdb,0xc0,0xfe,0x78,0xcd,0x5a,0xf4,
0x1f,0xdd,0xa8,0x33,0x88,0x07,0xc7,0x31,0xb1,0x12,0x10,0x59,0x27,0x80,0xec,0x5f,
0x60,0x51,0x7f,0xa9,0x19,0xb5,0x4a,0x0d,0x2d,0xe5,0x7a,0x9f,0x93,0xc9,0x9c,0xef,
0xa0,0xe0,0x3b,0x4d,0xae,0x2a,0xf5,0xb0,0xc8,0xeb,0xbb,0x3c,0x83,0x53,0x99,0x61,
0x17,0x2b,0x04,0x7e,0xba,0x77,0xd6,0x26,0xe1,0x69,0x14,0x63,0x55,0x21,0x0c,0x7d
]
rcon=[
0x8d,0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,0x1b,0x36,0x6c,0xd8,0xab,0x4d,0x9a,
0x2f,0x5e,0xbc,0x63,0xc6,0x97,0x35,0x6a,0xd4,0xb3,0x7d,0xfa,0xef,0xc5,0x91,0x39,
0x72,0xe4,0xd3,0xbd,0x61,0xc2,0x9f,0x25,0x4a,0x94,0x33,0x66,0xcc,0x83,0x1d,0x3a,
0x74,0xe8,0xcb,0x8d,0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,0x1b,0x36,0x6c,0xd8,
0xab,0x4d,0x9a,0x2f,0x5e,0xbc,0x63,0xc6,0x97,0x35,0x6a,0xd4,0xb3,0x7d,0xfa,0xef,
0xc5,0x91,0x39,0x72,0xe4,0xd3,0xbd,0x61,0xc2,0x9f,0x25,0x4a,0x94,0x33,0x66,0xcc,
0x83,0x1d,0x3a,0x74,0xe8,0xcb,0x8d,0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,0x1b,
0x36,0x6c,0xd8,0xab,0x4d,0x9a,0x2f,0x5e,0xbc,0x63,0xc6,0x97,0x35,0x6a,0xd4,0xb3,
0x7d,0xfa,0xef,0xc5,0x91,0x39,0x72,0xe4,0xd3,0xbd,0x61,0xc2,0x9f,0x25,0x4a,0x94,
0x33,0x66,0xcc,0x83,0x1d,0x3a,0x74,0xe8,0xcb,0x8d,0x01,0x02,0x04,0x08,0x10,0x20,
0x40,0x80,0x1b,0x36,0x6c,0xd8,0xab,0x4d,0x9a,0x2f,0x5e,0xbc,0x63,0xc6,0x97,0x35,
0x6a,0xd4,0xb3,0x7d,0xfa,0xef,0xc5,0x91,0x39,0x72,0xe4,0xd3,0xbd,0x61,0xc2,0x9f,
0x25,0x4a,0x94,0x33,0x66,0xcc,0x83,0x1d,0x3a,0x74,0xe8,0xcb,0x8d,0x01,0x02,0x04,
0x08,0x10,0x20,0x40,0x80,0x1b,0x36,0x6c,0xd8,0xab,0x4d,0x9a,0x2f,0x5e,0xbc,0x63,
0xc6,0x97,0x35,0x6a,0xd4,0xb3,0x7d,0xfa,0xef,0xc5,0x91,0x39,0x72,0xe4,0xd3,0xbd,
0x61,0xc2,0x9f,0x25,0x4a,0x94,0x33,0x66,0xcc,0x83,0x1d,0x3a,0x74,0xe8,0xcb
]
#returns a copy of the word shifted n bytes (chars)
#positive values for n shift bytes left, negative values shift right
defrotate(word,n):
returnword[n:]+word[0:n]
#iterate over each "virtual" row in the state table and shift the bytes
#to the LEFT by the appropriate offset
defshiftRows(state):
foriinrange(4):
state[i*4:i*4+4]=rotate(state[i*4:i*4+4],i)
#iterate over each "virtual" row in the state table and shift the bytes
#to the RIGHT by the appropriate offset
defshiftRowsInv(state):
foriinrange(4):
state[i*4:i*4+4]=rotate(state[i*4:i*4+4],-i)
#takes 4-byte word and iteration number
defkeyScheduleCore(word,i):
#rotate word 1 byte to the left
word=rotate(word,1)
newWord=[]
#apply sbox substitution on all bytes of word
forbyteinword:
newWord.append(sbox[byte])
#XOR the output of the rcon[i] transformation with the first part of the word
newWord[0]=newWord[0]^rcon[i]
returnnewWord
#expand 256 bit cipher key into 240 byte key from which
#each round key is derived
defexpandKey(cipherKey):
cipherKeySize=len(cipherKey)
assertcipherKeySize==32
#container for expanded key
expandedKey=[]
currentSize=0
rconIter=1
#temporary list to store 4 bytes at a time
t=[0,0,0,0]
#copy the first 32 bytes of the cipher key to the expanded key
foriinrange(cipherKeySize):
expandedKey.append(cipherKey[i])
currentSize+=cipherKeySize
#generate the remaining bytes until we get a total key size
#of 240 bytes
whilecurrentSize<240:
#assign previous 4 bytes to the temporary storage t
foriinrange(4):
t[i]=expandedKey[(currentSize-4)+i]
#every 32 bytes apply the core schedule to t
ifcurrentSize%cipherKeySize==0:
t=keyScheduleCore(t, rconIter)
rconIter+=1
#since we're using a 256-bit key -> add an extra sbox transform
ifcurrentSize%cipherKeySize==16:
foriinrange(4):
t[i]=sbox[t[i]]
#XOR t with the 4-byte block [16,24,32] bytes before the end of the
#current expanded key. These 4 bytes become the next bytes in the
#expanded key
foriinrange(4):
expandedKey.append(((expandedKey[currentSize-cipherKeySize])^(t[i])))
currentSize+=1
returnexpandedKey
#do sbox transform on each of the values in the state table
defsubBytes(state):
foriinrange(len(state)):
#print "state[i]:", state[i]
#print "sbox[state[i]]:", sbox[state[i]]
state[i]=sbox[state[i]]
#inverse sbox transform on each byte in state table
defsubBytesInv(state):
foriinrange(len(state)):
state[i]=sboxInv[state[i]]
#XOR each byte of the roundKey with the state table
defaddRoundKey(state,roundKey):
foriinrange(len(state)):
#print i
#print "old state value:", state[i]
#print "new state value:", state[i] ^ roundKey[i]
state[i]=state[i]^roundKey[i]
#Galois Multiplication
defgaloisMult(a,b):
p=0
hiBitSet=0
foriinrange(8):
ifb&1==1:
p^=a
hiBitSet=a&0x80
a<<=1
ifhiBitSet==0x80:
a^=0x1b
b>>=1
returnp%256
#mixColumn takes a column and does stuff
defmixColumn(column):
temp=copy(column)
column[0]=galoisMult(temp[0],2)^galoisMult(temp[3],1)^\
galoisMult(temp[2],1)^galoisMult(temp[1],3)
column[1]=galoisMult(temp[1],2)^galoisMult(temp[0],1)^\
galoisMult(temp[3],1)^galoisMult(temp[2],3)
column[2]=galoisMult(temp[2],2)^galoisMult(temp[1],1)^\
galoisMult(temp[0],1)^galoisMult(temp[3],3)
column[3]=galoisMult(temp[3],2)^galoisMult(temp[2],1)^\
galoisMult(temp[1],1)^galoisMult(temp[0],3)
#mixColumnInv does stuff too
defmixColumnInv(column):
temp=copy(column)
column[0]=galoisMult(temp[0],14)^galoisMult(temp[3],9)^\
galoisMult(temp[2],13)^galoisMult(temp[1],11)
column[1]=galoisMult(temp[1],14)^galoisMult(temp[0],9)^\
galoisMult(temp[3],13)^galoisMult(temp[2],11)
column[2]=galoisMult(temp[2],14)^galoisMult(temp[1],9)^\
galoisMult(temp[0],13)^galoisMult(temp[3],11)
column[3]=galoisMult(temp[3],14)^galoisMult(temp[2],9)^\
galoisMult(temp[1],13)^galoisMult(temp[0],11)
#mixColumns is a wrapper for mixColumn - generates a "virtual" column from
#the state table and applies the weird galois math
defmixColumns(state):
foriinrange(4):
column=[]
#create the column by taking the same item out of each "virtual" row
forjinrange(4):
column.append(state[j*4+i])
#apply mixColumn on our virtual column
mixColumn(column)
#transfer the new values back into the state table
forjinrange(4):
state[j*4+i]=column[j]
#mixColumnsInv is a wrapper for mixColumnInv - generates a "virtual" column from
#the state table and applies the weird galois math
defmixColumnsInv(state):
foriinrange(4):
column=[]
#create the column by taking the same item out of each "virtual" row
forjinrange(4):
column.append(state[j*4+i])
#apply mixColumn on our virtual column
mixColumnInv(column)
#transfer the new values back into the state table
forjinrange(4):
state[j*4+i]=column[j]
#aesRound applies each of the four transformations in order
defaesRound(state,roundKey):
#print "aesRound - before subBytes:", state
subBytes(state)
#print "aesRound - before shiftRows:", state
shiftRows(state)
#print "aesRound - before mixColumns:", state
mixColumns(state)
#print "aesRound - before addRoundKey:", state
addRoundKey(state, roundKey)
#print "aesRound - after addRoundKey:", state
#aesRoundInv applies each of the four inverse transformations
defaesRoundInv(state,roundKey):
#print "aesRoundInv - before addRoundKey:", state
addRoundKey(state, roundKey)
#print "aesRoundInv - before mixColumnsInv:", state
mixColumnsInv(state)
#print "aesRoundInv - before shiftRowsInv:", state
shiftRowsInv(state)
#print "aesRoundInv - before subBytesInv:", state
subBytesInv(state)
#print "aesRoundInv - after subBytesInv:", state
#returns a 16-byte round key based on an expanded key and round number
defcreateRoundKey(expandedKey,n):
returnexpandedKey[(n*16):(n*16+16)]
#create a key from a user-supplied password using SHA-256
defpasswordToKey(password):
sha256=hashlib.sha256()
sha256.update(password)
key=[]
forcinlist(sha256.digest()):
key.append(ord(c))
returnkey
#wrapper function for 14 rounds of AES since we're using a 256-bit key
defaesMain(state,expandedKey,numRounds=14):
roundKey=createRoundKey(expandedKey,0)
addRoundKey(state, roundKey)
foriinrange(1, numRounds):
roundKey=createRoundKey(expandedKey, i)
aesRound(state, roundKey)
#final round - leave out the mixColumns transformation
roundKey=createRoundKey(expandedKey, numRounds)
subBytes(state)
shiftRows(state)
addRoundKey(state, roundKey)
#14 rounds of AES inverse since we're using a 256-bit key
defaesMainInv(state,expandedKey,numRounds=14):
#create roundKey for "last" round since we're going in reverse
roundKey=createRoundKey(expandedKey, numRounds)
#addRoundKey is the same funtion for inverse since it uses XOR
addRoundKey(state, roundKey)
shiftRowsInv(state)
subBytesInv(state)
foriinrange(numRounds-1,0,-1):
roundKey=createRoundKey(expandedKey, i)
aesRoundInv(state, roundKey)
#last round - leave out the mixColumns transformation
roundKey=createRoundKey(expandedKey,0)
addRoundKey(state, roundKey)
#aesEncrypt - encrypt a single block of plaintext
defaesEncrypt(plaintext,key):
block=copy(plaintext)
expandedKey=expandKey(key)
aesMain(block, expandedKey)
returnblock
#aesDecrypt - decrypte a single block of ciphertext
defaesDecrypt(ciphertext,key):
block=copy(ciphertext)
expandedKey=expandKey(key)
aesMainInv(block, expandedKey)
returnblock
#return 16-byte block from an open file
#pad to 16 bytes with null chars if needed
defgetBlock(fp):
raw=fp.read(16)
#reached end of file
iflen(raw)==0:
return""
#container for list of bytes
block=[]
forcinlist(raw):
block.append(ord(c))
#if the block is less than 16 bytes, pad the block
#with the string representing the number of missing bytes
iflen(block)<16:
padChar=16-len(block)
whilelen(block)<16:
block.append(padChar)
returnblock
#encrypt - wrapper function to allow encryption of arbitray length
#plaintext using Output Feedback (OFB) mode
defencrypt(myInput,password,outputfile=None):
block=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]#plaintext
ciphertext=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]#ciphertext
#Initialization Vector
IV=[]
foriinrange(16):
IV.append(randint(0,255))
#convert password to AES 256-bit key
aesKey=passwordToKey(password)
#create handle for file to be encrypted
try:
fp=open(myInput,"rb")
except:
print"pyAES: unable to open input file -", myInput
sys.exit()
#create handle for encrypted output file
ifoutputfileisnotNone:
try:
outfile=open(outputfile,"w")
except:
print"pyAES: unable to open output file -", outputfile
sys.exit()
else:
filename=myInput+".aes"
try:
outfile=open(filename,"w")
except:
print"pyAES: unable to open output file -", filename
sys.exit()
#write IV to outfile
forbyteinIV:
outfile.write(chr(byte))
#get the file size (bytes)
#if the file size is a multiple of the block size, we'll need
#to add a block of padding at the end of the message
fp.seek(0,2)
filesize=fp.tell()
#put the file pointer back at the beginning of the file
fp.seek(0)
#begin reading in blocks of input to encrypt
firstRound=True
block=getBlock(fp)
whileblock!="":
iffirstRound:
blockKey=aesEncrypt(IV, aesKey)
firstRound=False
else:
blockKey=aesEncrypt(blockKey, aesKey)
foriinrange(16):
ciphertext[i]=block[i]^blockKey[i]
#write ciphertext to outfile
forcinciphertext:
outfile.write(chr(c))
#grab next block from input file
block=getBlock(fp)
#if the message ends on a block boundary, we need to add an
#extra block of padding
iffilesize%16==0:
outfile.write(16*chr(16))
#close file pointers
fp.close()
outfile.close()
#decrypt - wrapper function to allow decryption of arbitray length
#ciphertext using Output Feedback (OFB) mode
defdecrypt(myInput,password,outputfile=None):
block=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]#ciphertext
plaintext=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]#plaintext container
#convert password to AES 256-bit key
aesKey=passwordToKey(password)
#create handle for file to be encrypted
try:
fp=open(myInput,"rb")
except:
print"pyAES: unable to open input file -", myInput
sys.exit()
#create handle for file to be decrypted
try:
fp=open(myInput,"rb")
except:
print"pyAES: unable to open input file -", myInput
sys.exit()
#create handle for decrypted output file
ifoutputfileisnotNone:
try:
outfile=open(outputfile,"w")
except:
print"pyAES: unable to open output file -", filename
sys.exit()
else:
ifmyInput[-4:]==".aes":
filename=myInput[:-4]
print"Using", filename,"for output file name."
else:
filename=raw_input("output file name:")
try:
outfile=open(filename,"w")
except:
print"pyAES: unable to open output file -", filename
sys.exit()
#recover Initialization Vector, the first block in file
IV=getBlock(fp)
#get the file size (bytes) in order to handle the
#padding at the end of the file
fp.seek(0,2)
filesize=fp.tell()
#put the file pointer back at the first block of ciphertext
fp.seek(16)
#begin reading in blocks of input to decrypt
firstRound=True
block=getBlock(fp)
whileblock!="":
iffirstRound:
blockKey=aesEncrypt(IV, aesKey)
firstRound=False
else:
blockKey=aesEncrypt(blockKey, aesKey)
foriinrange(16):
plaintext[i]=block[i]^blockKey[i]
#if we're in the last block of text -> throw out the
#number of bytes represented by the last byte in the block
iffp.tell()==filesize:
plaintext=plaintext[0:-(plaintext[-1])]
#write ciphertext to outfile
forcinplaintext:
outfile.write(chr(c))
#grab next block from input file
block=getBlock(fp)
#close file pointers
fp.close()
outfile.close()
defprintUsage():
print"./pyAES.py [-e | -d ] [(optional) -o ]"
print"You will be prompted for a password after you specify the encryption/decryption args.\n"
sys.exit()
#gather command line arguments and validate input
defmain():
#containers for command line arguments
inputfile=None
outputfile=None
forainrange(len(sys.argv)):
ifsys.argv[a]=="-e":
try:
inputfile=sys.argv[a+1]
except:
inputfile=raw_input("File to encrypt:")
elifsys.argv[a]=="-d":
try:
inputfile=sys.argv[a+1]
except:
inputfile=raw_input("File to decrypt:")
ifsys.argv[a]=="-o":
try:
outputfile=sys.argv[a+1]
except:
pass
#print help message
if("-h"insys.argv)or("--help"insys.argv):
printUsage()
ifinputfileisNone:
print"Error: please specify options for encryption or decryption."
printUsage()
#encrypt file per user instructions
if"-e"insys.argv:
password=getpass.getpass("Password:")
print"Encrypting file:", inputfile
ifoutputfileisnotNone:
encrypt(inputfile, password, outputfile)
else:
encrypt(inputfile, password)
print"Encryption complete."
#decrypt file per user instructions
elif"-d"insys.argv:
password=getpass.getpass("Password:")
print"Decrypting file:", inputfile
ifoutputfileisnotNone:
decrypt(inputfile, password, outputfile)
else:
decrypt(inputfile, password)
print"Decryption complete."
if__name__=="__main__":
main()