Lab 01 - Introduction

Python Crash Course

Python Interactive Mode

Python is an easy to learn interactive programming language. Throughout this lab, we'll be using Python 2.7.

You can run Python code in two ways:

  • by writing a source file and running it (eventually, with some command line arguments)
  • by entering commands in interactive mode

To start interactive mode, simply open a terminal window and run python:

linux$ python

You can now write Python code just as you would in an actual program:

>>> print "Hello, SASC"

To quit interactive mode either press Ctrl+D or use:

>>> quit()

Interactive mode is useful when you want to quickly try something out (for example, testing decryption for a certain key) without going through the hassle of writing a new source file and running it.

Python Recipe #1 - Hail, Caesar!

In Python, indentation is important; it is used to organize code in blocks. For example, the following C code:

int foo(int a, int b) {
    int x;
    if (a > b) {
        x = a;
    } else {
        x = b;
    }
    return x
}

is (approximately) the same as the following in Python:

def foo(a, b):
    if a > b:
        x = a
    else:
        x = b
    return x

In this first recipe we'll see how to encrypt a single letter using Caesar's cipher.

alphabet='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
def caesar_enc(letter):
  if letter < 'A' or letter > 'Z':
    print 'Invalid letter'
    return
  else:
    return alphabet[(ord(letter) - ord('A') + 3) % len(alphabet)]

Create a new file named caesar.py containing the code above. To test the code, open the interpreter and try the following:

linux$ python
>>> from caesar import *
>>> print alphabet
>>> alphabet[0]
>>> ord('A')
>>> len(alphabet)
>>> ord('D') - ord('A')
>>> 28 % 26
>>> -1 % 26
>>> caesar_enc('D')
>>> caesar_enc('Z')
>>> caesar_enc('B')

Python Exercise #1 - Decrypting a letter

Add a caesar_dec function to caesar.py, which decrypts a single letter encrypted using Caesar's cipher.

Python Recipe #2 - Encrypting a string

We'll now expand our function to take string as input. First, a little intro to Python for loops. Some examples:

for i in [1, 2, 3]:
    print i

In this first example, i iterates through the values in list [1, 2, 3]. The code is similar to the classical C code:

for (int i = 1; i <= 3; i++) {
    printf("%d\n", i);
}

To create lists of integers use the range function:

for i in range(3):
    print i

Execute the code above in the interpreter. Using the range function with two parameters, change the above to print integers 1 through 10.

In Python, for can iterate through multiple types of objects, including strings. Try the below:

for letter in 'ABCD':
    print letter

We will now use the for instruction to expand our caesar_enc function:

alphabet='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
def caesar_enc_string(plaintext):
    ciphertext = ''
    for letter in plaintext:
        ciphertext = ciphertext + caesar_enc(letter)
    return ciphertext
 

Test the above by starting a new interpreter; this time, we'll skip the from caesar import * part by running the source file before starting interactive mode:

linux$ python -i caesar.py
>>> test = 'HELLO'
>>> test + 'WORLD'
>>> caesar_enc_string(test)

Another way to run things, which can be very useful in general is to use a main() function and write your program script as follows:

'test_caesar.py'
import sys
import random
import string
import operator
 
alphabet='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
 
def caesar_enc(letter):
  if letter < 'A' or letter > 'Z':
    print 'Invalid letter'
    return
  else:
    return alphabet[(ord(letter) - ord('A') + 3) % len(alphabet)]
 
def caesar_enc_string(plaintext):
    ciphertext = ''
    for letter in plaintext:
        ciphertext = ciphertext + caesar_enc(letter)
    return ciphertext
 
def main():
  m = 'BINEATIVENIT'
  c = caesar_enc_string(m)
  print c
 
 
if __name__ == "__main__":
  main()

Then you can simply run the program, or type the following in a terminal:

python test_caesar.py

Python Exercise #2 - Decrypting a string

Add the corresponding caesar_dec_string function.

Python Recipe #3 - Shift ciphers

Python allows passing default values to parameters:

def foo(a, b = 3):
    print a, b
>>> foo(1)
>>> foo(1, 2)

We can use default parameter values to expand our caesar_enc function to take the key as an additional parameter, without breaking compatibility with our previous code.

def caesar_enc(letter, k = 3):
    if letter < 'A' or letter > 'Z':
        print 'Invalid letter'
        return None
    else:
        return alphabet[(ord(letter) - ord('A') + k) % len(alphabet)]
 
def caesar_enc_string(plaintext, k = 3):
    ciphertext = ''
    for letter in plaintext:
        ciphertext = ciphertext + caesar_enc(letter, k)
    return ciphertext

To test the new functions, try the below:

linux$ python -i caesar.py
>>> caesar_enc_string('HELLO')
>>> caesar_enc_string('HELLO', 0)
>>> caesar_enc_string('HELLO', 1)

Python Exercise #3 - Shift ciphers

Using default parameters, expand your shift cipher decryption functions to support arbitrary keys.

Python Recipe #4 - Format conversions

import binascii
 
def strxor(a, b): # xor two strings (trims the longer input)
  return "".join([chr(ord(x) ^ ord(y)) for (x, y) in zip(a, b)])
 
def hexxor(a, b): # xor two hex strings (trims the longer input)
  ha = a.decode('hex')
  hb = b.decode('hex')
  return "".join([chr(ord(x) ^ ord(y)).encode('hex') for (x, y) in zip(ha, hb)])
 
def bitxor(a, b): # xor two bit strings (trims the longer input)
  return "".join([str(int(x)^int(y)) for (x, y) in zip(a, b)])
 
def str2bin(ss):
  """
    Transform a string (e.g. 'Hello') into a string of bits
  """
  bs = ''
  for c in ss:
    bs = bs + bin(ord(c))[2:].zfill(8)
  return bs
 
def hex2bin(hs):
  """
    Transform a hex string (e.g. 'a2') into a string of bits (e.g.10100010)
  """
  bs = ''
  for c in hs:
    bs = bs + bin(int(c,16))[2:].zfill(4)
  return bs
 
def bin2hex(bs):
  """
    Transform a bit string into a hex string
  """
  return hex(int(bs,2))[2:-1]
 
def byte2bin(bval):
  """
    Transform a byte (8-bit) value into a bitstring
  """
  return bin(bval)[2:].zfill(8)
 
def str2int(ss):
  """
    Transform a string (e.g. 'Hello') into a (long) integer by converting
    first to a bistream
  """
  bs = str2bin(ss)
  li = int(bs, 2)
  return li
 
def int2hexstring(bval):
  """
    Transform an int value into a hexstring (even number of characters)
  """
  hs = hex(bval)[2:]
  lh = len(hs)
  return hs.zfill(lh + lh%2)
 
def bin2str(bs):
  """
    Transform a binary srting into an ASCII string
  """
  n = int(bs, 2)
  return binascii.unhexlify('%x' % n)

Python Exercise #4 - Format conversions

Find the plaintext messages for the following ciphertexts knowing that the cipher is the XOR operation (ciphertext = plaintext XOR key) and the key is “abcdefghijkl”.

C1 = "000100010001000000001100000000110001011100000111000010100000100100011101000001010001100100000101"

C2 = "02030F07100A061C060B1909"
sasc/laboratoare/01.txt · Last modified: 2017/02/21 11:28 by dan.dragan
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0