单片机部分
在Halmstad University曾经被我认为不可能通过的一门课,昨天终于完结了Projekt,十分不容易,是关于Atmel Sam3x8e 的开发。做的是一个模拟气象站,对气温的实时监控和存储,对阳光方向的判断,以及温度警报器。
大致是这样
(视频在b站审核,csdn挂视频只能从b站拉)
3945c3ba127f72707448dbbc84e978f0
附上源代码
ADC.c
#include "at91sam3x8.h"
#include <stdio.h>
#include "PWM.h"
#include "display.h"
#include "keypad.h"
void initADC()
{
*AT91C_PMC_PCER1 = (1 << 5); //ENABLE CLOCK FOR ADC
*AT91C_ADCC_MR = (2 << 8); //SET PRESCALER TO 2
}
float ADC_Right()
{
*AT91C_ADCC_CHER = (1 << 1); //Select channel 1
*AT91C_ADCC_CR = (1 << 1); //Start an ADC
float temp;
while(1)
if((*AT91C_ADCC_SR & (1 << 24)) == (1 << 24))
{
temp = *AT91C_ADCC_LCDR & 0xFFF;
temp = (temp / 0xFFF) * 3.3;
return temp;
}
}
float ADC_Left() // more closed to temp-sensor
{
*AT91C_ADCC_CHER = (1 << 2); //Select channel 2
*AT91C_ADCC_CR = (1 << 1); //Start an ADC
float temp;
while(1)
if((*AT91C_ADCC_SR & (1 << 24)) == (1 << 24))
{
temp = *AT91C_ADCC_LCDR & 0xFFF;
temp = (temp / 0xFFF) * 3.3;
*AT91C_ADCC_CHDR = (1 << 2); //Disable channel 2
return temp;
}
}
void changeDirection()
{
PrintToDisplay("Please put under the light ");
PrintToDisplay("The resistance is the dir ");
PrintToDisplay("Press # to return ");
while(1)
{
initADC();
float left = ADC_Left();
initADC();
float right = ADC_Right();
if (left - 1 < 1e-2 && right - left > 0.4) turnServor(1838);
else if (right - 1.2 < 1e-2 && left - right > 0.5) turnServor(5705);
int key = -1;
key = key_pad();
if (key == 12) return;
}
}
alarm.c
#include <stdio.h>
#include <stdlib.h>
#include "display.h"
#include "temp.h"
#include "keypad.h"
int alarmchecked = 1;
typedef struct stats_alarm
{
float lower;
float upper;
}stats_alarm;
stats_alarm alarm;
void resetAlarm()
{
alarm.lower = -20;
alarm.upper = 25;
}
void updateAlarmLow(float low)
{
alarm.lower = low;
}
void updateAlarmUp(float up)
{
alarm.upper = up;
}
void checkAlarm(float temp)
{
if (temp - alarm.upper > 0.01)
{
PrintToDisplay(" ");
PrintToDisplay("Temp too high!!! Please check ");
puts("Temp too high");
alarmchecked = 0;
printf("temp > upper : %.2f > %.2f\n", temp, alarm.upper);
return;
}
if (alarm.lower - temp > 0.01)
{
PrintToDisplay(" ");
PrintToDisplay("Temp too low !!! Please check ");
puts("Temp too low");
alarmchecked = 0;
printf("temp < lower : %.2f < %.2f\n", temp, alarm.lower);
return;
}
}
void changeAlarm()
{
PrintToDisplay("1. Update top temp ");
PrintToDisplay("2. Update low temp ");
int key = -1;
while (key != 1 && key != 2) key = key_pad();
Clear_Display();
if (key == 1)//change up
{
PrintToDisplay("Please Input New Top Temp End*");
float top = RecupValue(1);
alarm.upper = top;
printf("%.2f\n", top);
}
else
{
PrintToDisplay("Please Input New Low Temp End*");
float down = RecupValue(2);
alarm.lower = down;
printf("%.2f\n", down);
}
}
void printAlarm()
{
if (alarm.lower > alarm.upper)
{
PrintToDisplay("Temp not normal please check! ");
return;
}
char infoAlarm[100] = {0};
sprintf(infoAlarm, "Alarm lower:%.2f upper:%.2f \0", alarm.lower, alarm.upper);
int i = 0;
while (infoAlarm[i] != '\0')
{
Print_From_Data(infoAlarm[i]);
i++;
}
}
data.c
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include "linkedList.h"
#include "display.h"
typedef struct stats_vars
{
float average;
float min;
float max;
}stats_vars;
float average(List * list,int n)
{
float av = 0;
Item * item;
if (list->head != NULL)
for (item = list->head; NULL != item; item = item->next)
av+=item->data;
return av /= n;
}
float min(List * list)
{
float min = 0;
Item * item;
if (list->head != NULL)
{
min=list->head->data;
for (item = list->head; NULL != item; item = item->next)
if(min>item->data)
min = item->data;
}
return min;
}
float max(List * list)
{
float max = 0;
Item * item;
if (list->head != NULL)
{
max=list->head->data;
for (item = list->head; NULL != item; item = item->next)
if(max<item->data)
max = item->data;
}
return max;
}
void print_data(stats_vars data)
{
char info[100] = {0};
sprintf(info, "min:%.2f max:%.2f avg:%.2f \0", data.min, data.max, data.average);
printf("%s\n", info);
int i = 0;
while (info[i] != '\0')
{
Print_From_Data(info[i]);
i++;
}
}
stats_vars calc_stats(List * list)
{
stats_vars stats;
stats.average = average(list, list->size);
stats.min = min(list);
stats.max = max(list);
return stats;
}
delay.c
void delay(int Value){
for(int i = 0; i < Value; i++){
asm("nop");
}
}
doubleLinkedList.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "linkedList.h"
#include "data.h"
#include "display.h"
typedef struct Ditem_s
{
List * day;
stats_vars stats;
struct Ditem_s * next;
struct Ditem_s * prev;
}DItem;
typedef struct Dlist_s
{
int size;
DItem * head;
DItem * tail;
}DList;
DList * Dcreate ()
{
DList * list;
list = calloc (1, sizeof *list);
if (NULL == list) return 0;
list->size = 0;
return list;
}
int Dappend (DList * list, List * day)
{
DItem * item;
item = malloc(sizeof *item);
if (NULL == item) return 0;
item->day = day;
item->stats = calc_stats(day);
item->next = NULL;
if (NULL == list->head)
{
list->head = item;
list->tail = item;
item->prev = NULL;
}
else
{
list->tail->next = item;
item->prev = list->tail;
list->tail = item;
}
list->size++;
return 1;
}
void rem_head (DList * list)
{
DItem * old_item;
old_item = list->head;
if(old_item == NULL) printf("List is empty");
else
{
if(old_item->next == NULL) printf("Error!!");
old_item = list->head;
list->head = list->head->next;
}
destroy(old_item->day);
free(old_item);
}
void Ddestroy (DList * list)
{
DItem * tmp;
while (NULL != list->head)
{
tmp = list->head->next;
destroy(list->head->day);
free (list->head);
list->head = tmp;
}
free (list);
}
void Dprint_fwd (DList * list) //print
{
DItem * item;
if (NULL == list->head) puts("Now list is empty");
else {
puts("");
for (item = list->head; NULL != item; item = item->next) print_data(item->stats);
puts("");
}
}
void Dprint_rev (DList * list)
{
DItem * item;
if (NULL == list->head) puts("Now list is empty");
else {
puts("");
for (item = list->tail; NULL != item; item = item->prev) print(item->day);
puts("");
}
}
keypad.c
#include "at91sam3x8.h"
int key_pad(void){
int rowIndex[4] = {5,2,3,4};
int colIndex[3] = {8,9,7};
int value = -1;
//Clear OE KEY BUS (Active Low)
*AT91C_PIOD_CODR = 1 << 2;
// Make all Column pin as output
//Set all Column pin as high 7,8,9
*AT91C_PIOC_PER = 0x380;
*AT91C_PIOC_OER = 0x380;
*AT91C_PIOC_SODR = 0x380;
// Loop Column 0 & 1 &3
for(int col = 0; col < 3; col++)
{
//Clear one column at the time
*AT91C_PIOC_CODR = (1 << colIndex[col]);
//Loop Row
for(int row = 0; row < 4; row++)
{
int readRow = *AT91C_PIOC_PDSR;
//Read row and check if bit is zero
if ((~readRow & (1 << rowIndex[row])) == (1 << rowIndex[row]))
value = row*3+col+1;
}//end loop Row
//Set the column again
*AT91C_PIOC_SODR=(1<<colIndex[col]);
}
// Make all Column pin as input
*AT91C_PIOC_PER = 0x380;
*AT91C_PIOC_ODR = 0x380;
return value;
}
linkedList.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct item_s {
float data;
struct item_s * next;
}Item;
typedef struct list_s {
int size;
Item * head;
Item * tail;
}List;
List * create ()
{
List * list;
list = calloc (1, sizeof *list);
if (NULL == list) printf ("EXIT_FAILURE, %s: calloc", __func__);
list->size = 0;
return list;
}
int append (List * list,float data)
{
Item * item;
item = malloc (sizeof *item);
if (NULL == item) {
printf("EXIT_FAILURE, %s: malloc", __func__);
return 0;
}
item->data = data;
item->next = NULL;
if (NULL == list->head) {
list->head = item;
list->tail = item;
}
else {
list->tail->next = item;
list->tail = item;
}
list->size++;
return 1;
}
void print (List * list)
{
Item * item;
if (NULL == list->head) puts("Now list is empty");
else {
puts("");
for (item = list->head; NULL != item; item = item->next) printf (" %.3f", item->data);
puts("");
}
}
void destroy (List * list)
{
Item * tmp;
while (NULL != list->head)
{
tmp = list->head->next;
free (list->head);
list->head = tmp;
}
free (list);
}
temp.c
#include "at91sam3x8.h"
#include "core_cm3.h"
#include "delay.h"
#include "alarm.h"
#include "linkedList.h"
#include "doubleLinkedList.h"
#include "stdio.h"
char tempFlag = 0;
int time = 0;
int previousKey = 0;
int onemin = 60 * 1000;
int min_day = 24 * 60;
int mode_fast_test = 0;//Bool
List * tempDay;
DList * tempWeek;
void InitTemp()
{
*AT91C_PMC_PCER = 134221824; //ENABLE CLOCK FOR TC0 and PIOB
*AT91C_TC0_CMR = 0; //CHOOSE TIMER_CLOCK1 AS TCCLK
*AT91C_TC0_CCR = 5; //ENABLE CLOCK AND SW RESET
*AT91C_TC0_CMR = 0x60000; //SET REGB TO RISING
*AT91C_PIOB_PER = (1 << 25); //ENABLE PIOB25
*AT91C_PIOB_OER = 1 << 25;
*AT91C_PIOB_CODR = 1 << 25;
NVIC_ClearPendingIRQ((IRQn_Type)27);
NVIC_EnableIRQ((IRQn_Type)27);
}
void StartTemp()
{
*AT91C_PIOB_OER = (1 << 25); //LOW START PULSE
delay(25);
*AT91C_PIOB_ODR = (1 << 25); //END START PULSE
*AT91C_TC0_CCR = 4; //RESET TC
unsigned int interrupt = *AT91C_TC0_SR;
*AT91C_TC0_IER = (1 << 6); //ENABLE INTERRUPT ON LDRBS
delay(35000);
}
double ReadTemp()
{
unsigned int a = *AT91C_TC0_RA;
unsigned int b = *AT91C_TC0_RB;
double timeUs = (double)(b - a) / (double)42.0;
double temp = timeUs / 5 - 273.15;
return temp;
}
void TC0_Handler()
{
*AT91C_TC0_IDR = (1 << 6); //DISABLE INTERRUPT ON LDRBS
tempFlag = 1;
}
void addToList()
{
int res;
StartTemp();
float temp = ReadTemp();
while(temp < -100 || temp > 100)
{
StartTemp();
temp = ReadTemp();
}
printf("real time temp : %.2f\n", temp);
if (alarmchecked) checkAlarm(temp);
if(time < min_day)
{
res = append(tempDay, temp);
if(!res) rem_head(tempWeek);
}
else
{
time = 0;
res = Dappend(tempWeek,tempDay);
tempDay = create();
if(!res)
{
rem_head(tempWeek);
tempDay = create();
}
}
}
systick.c
#include "core_cm3.h"
#define ticks 84000
int handler = 0;
int alarmSys = 0;
void InitSystick()
{
SysTick_Config(ticks); //set systick to 1 ms
}
void SysTick_Handler()
{
handler++;
alarmSys++;
}
display.c
#include "at91sam3x8.h"
#include "delay.h"
#include "systick.h"
#include "keypad.h"
#include "stdlib.h"
#include "stdio.h"
#include "stdbool.h"
void Initialize_Pins_Display()
{
* AT91C_PMC_PCER = (3 << 13); //enable clock on pio C and D
* AT91C_PIOC_PER = 0x3BC; //enable pioc 2,3,4,5,7,8,9
* AT91C_PIOC_ODR = 0x3BC; //set pins as input
* AT91C_PIOD_PER = (1 << 2); //enable piod 2
* AT91C_PIOD_OER = (1 << 2); //set as output
* AT91C_PIOD_SODR = (1 << 2); //set piod2 output as 1(turn off oe)
//display
* AT91C_PMC_PCER = (3 << 13); //enable clock on pio C and D
* AT91C_PIOC_PER = (0xFF << 2); //enable pioc 2-9
* AT91C_PIOC_PER = (0xFF << 12); //enable pioc 12-19
* AT91C_PIOC_ODR = (0xFF << 2); //set pins 2-9 as input(databus)
* AT91C_PIOC_OER = (0xFF << 12); //set pins 12-19 as output
* AT91C_PIOC_SODR = (0x9 << 14); //set wr, rd, ce as high
* AT91C_PIOC_SODR = (1 << 12); //set pins 12 to 1 (oe = 1)
* AT91C_PIOD_PER = 1; //enable pin0 piod
* AT91C_PIOD_OER = 1; //set pin0 as output
}
unsigned char Read_Status_Display()
{
//pin 34 to 41
unsigned char Temp;
*AT91C_PIOC_ODR = (255 << 2);// MAKE DATABUS AS INPUT
*AT91C_PIOC_SODR =(1 << 13); // sets the dir pin to high // input
*AT91C_PIOC_CODR = (1 << 12); // clears the OE
*AT91C_PIOC_SODR = (1 << 14);// set C/D to high
*AT91C_PIOC_CODR = (1 << 15); // clear CE (chip enable)
*AT91C_PIOC_CODR = (1 << 16); // clear read control (RD)
delay(10);
Temp = (*AT91C_PIOC_PDSR >> 2);
*AT91C_PIOC_SODR = (1 << 15); // set CE (chip enable)
*AT91C_PIOC_SODR = (1 << 16); //set read control (RD)
*AT91C_PIOC_SODR = (1 << 12); // disable the OE
*AT91C_PIOC_CODR =(1 << 13); // set dir pin to low //output
return Temp;
}
void Write_Command_2_Display(unsigned char Command)
{
while(1){
if((Read_Status_Display() & (3 << 0)) == (3 << 0)){
*AT91C_PIOC_CODR = (255 << 2); // clear the pin form 34 to 41
*AT91C_PIOC_SODR = (Command << 2);// set Command to databus
*AT91C_PIOC_CODR =(1 << 13); // set dir pin to low //output
*AT91C_PIOC_CODR = (1 << 12); // clears/enable the OE
*AT91C_PIOC_OER = (255 << 2);// MAKE DATABUS AS OUTPUT
*AT91C_PIOC_SODR = (1 << 14);// set C/D to high
*AT91C_PIOC_CODR = (1 << 15); // clear CE (chip enable)
*AT91C_PIOC_CODR = (1 << 17); // CLEAR WRITE DISPLAY
delay(10);
*AT91C_PIOC_SODR = (1 << 15); // SET CE (chip enable)
*AT91C_PIOC_SODR = (1 << 17); // SET WRITE DISPLAY
*AT91C_PIOC_SODR = (1 << 12); // disable the OE
*AT91C_PIOC_ODR = (255 << 2);// MAKE DATABUS AS INPUT
break;
}
}
}
void Write_Data_2_Display(unsigned char Data)
{
while(1){
if((Read_Status_Display() & (3 << 0)) == (3 << 0)){
*AT91C_PIOC_CODR = (255 << 2); // clear the pin form 34 to 41
*AT91C_PIOC_SODR = (Data << 2); //Set Data to databus
*AT91C_PIOC_CODR =(1 << 13); // set dir pin to low //output
*AT91C_PIOC_CODR = (1 << 12); // clears/enable the OE
*AT91C_PIOC_OER = (255 << 2);// MAKE DATABUS AS OUTPUT
*AT91C_PIOC_CODR = (1 << 14);// clear C/D
*AT91C_PIOC_CODR = (1 << 15); // clear CE (chip enable)
*AT91C_PIOC_CODR = (1 << 17); // CLEAR WRITE DISPLAY
delay(10);
*AT91C_PIOC_SODR = (1 << 15); // SET CE (chip enable)
*AT91C_PIOC_SODR = (1 << 17); // SER WRITE DISPLAY
*AT91C_PIOC_SODR = (1 << 12); // disable the OE
*AT91C_PIOC_ODR = (255 << 2);// MAKE DATABUS AS INPUT
break;
}
}
}
void Init_Display()
{
*AT91C_PIOD_CODR = (1 << 0);
delay(10);
*AT91C_PIOD_SODR = (1 << 0);
Write_Data_2_Display(0x00);
Write_Data_2_Display(0x00);
Write_Command_2_Display(0x40);//Set text home address
Write_Data_2_Display(0x00);
Write_Data_2_Display(0x40);
Write_Command_2_Display(0x42); //Set graphic home address
Write_Data_2_Display(0x1e);
Write_Data_2_Display(0x00);
Write_Command_2_Display(0x41); // Set text area
Write_Data_2_Display(0x1e);
Write_Data_2_Display(0x00);
Write_Command_2_Display(0x43); // Set graphic area
Write_Command_2_Display(0x80); // text mode
Write_Command_2_Display(0x94); // Text on graphic off
}
void Clear_Display()
{
Write_Data_2_Display(0x00);
Write_Command_2_Display(0x24);
for(int i = 0; i< (16*40); i++){
Write_Data_2_Display(0x00);
Write_Command_2_Display(0xC0);
}
Write_Data_2_Display(0x00);
Write_Command_2_Display(0x24);
}
void Print_From_Data(char key)
{
key = key-' ';
Write_Data_2_Display(key);
Write_Command_2_Display(0xC0);
}
void PrintToDisplay(char string[])
{
int i = 0;
while (string[i] != '\0')
{
Print_From_Data(string[i]);
i++;
}
}
float RecupValue(int input)
{
int key = -1;
char value[10]={0};
int i = 0;
int prekey = input;
int flag = 1;
while(key != 10)
{
key = key_pad();
if(key != -1 && prekey != key && key != 11 && key != 12)
{
value[i] = key + '0';
Print_From_Data(value[i]);
i++;
prekey = key;
}
if (key == 11 && prekey != key && key != 12)
{
value[i] = '0';
Print_From_Data(value[i]);
i++;
prekey = key;
}
if (key == 12 && prekey != key)
{
Print_From_Data('-');
flag = -1;
prekey = key;
}
}
value[i] = '\0';
return atof(value) * flag;
}
PWM.c
#include "at91sam3x8.h"
void initPower(){
*AT91C_PMC_PCER1 = (1 << 4);
*AT91C_PIOC_ABMR |= (1 << 22);//Activate peripheral B to control the pin in REG_PIOB_ABSR
*AT91C_PIOC_PDR = (1 << 22);
*AT91C_PWMC_ENA = (1 << 5);
*((volatile unsigned int*)0x400942A0) |= 5;
*AT91C_PWMC_CH5_CPRDR |= 52500; //52500
*AT91C_PWMC_CH5_CDTYR |= 2625; //52500 / 20
}
void turnServor(int degree){
*AT91C_PWMC_CH5_CDTYR = degree;
}
main.c
#include "at91sam3x8.h"
#include "core_cm3.h"
#include "core_cmFunc.h"
#include "core_cmInstr.h"
#include "system_sam3x.h"
#include <stdio.h>
#include <stdlib.h>
#include "temp.h"
#include "delay.h"
#include "PWM.h"
#include "systick.h"
#include "linkedList.h"
#include "doubleLinkedList.h"
#include "display.h"
#include "alarm.h"
#include "keypad.h"
#include "ADC.h"
void writeMenu()
{
Clear_Display();
PrintToDisplay("1. Show Temperatures ");
PrintToDisplay("2. Find Sun ");
PrintToDisplay("3. Show Alarm ");
PrintToDisplay("4. Fast Mode ");
PrintToDisplay("5. Update Alarm ");
PrintToDisplay("#. Clean ");
}
void operation()
{
int key = key_pad();
if(key != previousKey)
{
switch(key){
case 1: Clear_Display();
if(mode_fast_test) PrintToDisplay("Mode fast ... # to back ");
else PrintToDisplay("# to back ");
Dprint_fwd(tempWeek);
break;
case 2: Clear_Display();
PrintToDisplay("Now Searching the light... ");
changeDirection();
break;
case 3: Clear_Display();
printAlarm();
PrintToDisplay(" ");
PrintToDisplay("# to back ");
break;
case 4: if (mode_fast_test)
{
PrintToDisplay("Do Not press again! ");
break;
}
mode_fast_test = 1;
onemin = 1000;
min_day = 24; // one hour
PrintToDisplay(" Now Fast Mode ... ");
break;
case 5: Clear_Display();
changeAlarm();
case 12:Clear_Display();
alarmchecked = 1;
writeMenu();
break;
}
previousKey = key;
}
}
void main(){
SystemInit();
InitSystick();
Initialize_Pins_Display();
Init_Display();
Clear_Display();
InitTemp();
initADC();
initPower();
tempDay = create();
tempWeek = Dcreate();
resetAlarm();
writeMenu();
while(1)
{
if(alarmSys % onemin == 0)
{
time++;
printf("time : %d ",time);
addToList();
}
operation();
int key = -1;
key = key_pad();
if (key == 12)
if (mode_fast_test)
{
writeMenu();
PrintToDisplay(" Now Fast Mode ... ");
}
}
}
十分不容易,身边就三个中国的交换生全部退了这个课,但我相信关于代码的东西我都能做到,九牛二虎之力后终于完成了这个项目,现在就等着1.13号当面考试这个项目了,好运~
下面是Python的结课项目,与其说是项目不如说是个作业,反正算法上来看和我们平常训练的相比就是大学生虐小学生。
Python部分
大致就是写一个什么凯撒密码?没有这么玄乎,就是ascii码移位 + 文件输入输出,水的一批。
这个是介绍:
Introduction to Linux and Python - DI4016 – HT2019 Python Programming Assignment.
Basic Text Encryption / Decryption
In this mini-project, you will create a Python program which implements functions for
encryption and decryption of a text using the “Caesar Cipher”.
You should work on the project individually, at home or during the Lab sessions. You can ask
the Lab assistants for help if you have any questions. When you finish, please send the
source code (as .py file) to mohamed-rafik.bouguelia@hh.se before 15 January 2020.
Specify your name(s) as a comment (starting with #) at the beginning of the source code.
NOTE: Please be aware that any tentative of plagiarism or copying/modifying the source
code from another student will be detected and will result in the project not being accepted
from both students.
Introduction
In cryptography, Caesar’s cipher is one of the simplest and most widely known encryption
techniques. The action of a Caesar cipher is to replace each letter within a text with a
different letter, using a fixed number of places down the alphabet [1].
For example, to encrypt a given text, we can use a left shift of three characters, so that (for
example) each occurrence of the letter E in the text becomes B in the encrypted text.
This transformation can be represented by aligning two alphabets : the original plain
alphabet, and the cipher alphabet. The cipher alphabet is the plain alphabet shifted left by
some number of positions n. This number of positions (n=3 in the previous example) plays
the role of an encryption/decryption key.
Plain Alphabet : ABCDEFGHIJKLMNOPQRSTUVWXYZ
Cipher Alphabet : XYZABCDEFGHIJKLMNOPQRSTUVW
To encrypt a message using a given key (e.g. n=3), a person looks up each letter of the
message in the Plain Alphabet and writes down the corresponding letter in the Cipher
Alphabet. Example:
Clear Message: « THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG »
Encrypted message: « QEB NRFZH YOLTK CLU GRJMP LSBO QEB IXWV ALD »
To decrypt the encrypted message, we repeat the same process in reverse (i.e. with a right
shift of 3 positions).
Project Description
- Encryption function
Introduction to Linux and Python - DI4016 – HT2019 Python Programming Assignment.
First, you are asked to define a function encrypt(msg, n) that takes as arguments a
text msg (as a string) and a key n (as an integer number). This function is supposed to shift
all the characters in the text message to the left by n positions, and return a new encrypted
message.
If msg contains any characters that are not part of the alphabet (such as spaces etc.), then
you can keep them unchanged (i.e. no need to encrypt them).
Once your function encrypt(message, n) is defined, you can test it on some text (e.g.
“THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG”) and check if it returns the
expected encrypted text (e.g. “QEB NRFZH YOLTK CLU GRJMP LSBO QEB IXWV
ALD” if you chose n = 3). - Decryption function
Second, you are asked to define a function decrypt(encrypted_msg, n) that takes
as arguments an encrypted text encrypted_msg (as a string) and a key n (as an integer
number). This function is supposed to decrypt the text message by shifting all the characters
of the encrypted message to the right by n positions, and return the decrypted message.
If encrypted_msg contains any characters that are not part of the alphabet (such as
spaces etc), then you can keep them unchanged (i.e. no need to decrypt them).
Once your function decrypt(encrypted_msg, n) is defined, you can test it on some
text (e.g. “QEB NRFZH YOLTK CLU GRJMP LSBO QEB IXWV AL”) and check if it
returns the correct decrypted text (e.g. “THE QUICK BROWN FOX JUMPS OVER THE
LAZY DOG” if you chose n = 3). - Reading / Writing to text a file
In this part, you are asked to write a code to read each line from a text file named
clearText.txt, encrypt the line by calling the encrypt function that you defined
previously, then write (append) the encrypted line to another file encryptedText.txt.
Introduction to Linux and Python - DI4016 – HT2019 Python Programming Assignment.
To read from an existing file in Python you first need to open the file in read mode using the
function open(“clearText.txt”, “r”) (note the second argument “r” which
stands for “read mode”) and then read the lines from the file by calling the function
readlines() as follows:
f1 = open(“clearText.txt”, “r”)
lines = f1.readlines()
The variable lines consists of a list of strings (corresponding to lines). So, you can iterate
over each line in lines using a for loop.
To append an encrypted line to a file (i.e. write the line without overwriting the previous
content), you can open the file in append mode and then write to the file by calling the
function write(…) as follows:
f2 = open(“encryptedText.txt”, “a”)
lines = f2.write(encrypted_line) - Letter frequency analysis
The encryption method that you implemented previously is not very secure. It is possible to find
the original text from the encrypted text by performing a process called frequency analysis.
The reason why this kind of encryption is not secure, is because each letter in the original text is
always encrypted the same way. For example, the most common letter “E” might always be
encrypted as “B”, so a hacker finds that “B” is the most common letter in the encrypted text then
he can assume it represents “E”. From this, the hacker can deduce that the original text has been
encrypted by shifting letters to the left by 3 positions. Now, that he knows the key (i.e. 3), he can
easily decrypt the text. This process can be carried out for all letters, and it is called frequency
analysis.
A first step to perform frequency analysis is to count the frequency (or number of occurrence) of
each letter in the encrypted text.
In this part of the project, you are asked to write a function that computes the number of
occurrences of each letter of the alphabet in the encrypted text. The output should correspond
to something like the following (of course, the numbers will depend on the text that you use) :
A occurs 29 times in the encrypted text
B occurs 15 times in the encrypted text
C occurs 18 times in the encrypted text
… etc …
Z occurs 7 times in the encrypted text
[1] Caesar_cipher, https://en.wikipedia.org/wiki/Caesar_cipher
#Author : Lubin Gan
def encrypt(msg, n):
list_msg = list(msg)
i = 0
res = ""
while i < len(list_msg):
if ord(list_msg[i]) >= 65 + n and ord(list_msg[i]) <= 90:
res += chr(ord(list_msg[i]) - n)
if ord(list_msg[i]) >= 65 and ord(list_msg[i]) < 65 + n:
res += chr(90 - n + 1)
if list_msg[i] == " ":
res += " "
i += 1
return res
def decrypt(msg, n):
list_msg = list(msg)
i = 0
res = ""
while i < len(list_msg):
if ord(list_msg[i]) >= 65 and ord(list_msg[i]) <= 90 - n:
res += chr(ord(list_msg[i]) + n)
if ord(list_msg[i]) >= 90 - n + 1:
res += chr(65 + n)
if list_msg[i] == " ":
res += " "
i += 1
return res
def frequency():
res = []
for i in range(26):
res.append(0)
f3 = open("encryptedText.txt", "r")
lines = f3.readlines()
for line in lines:
for i in range(len(line)):
if (ord(line[i]) - 65) != -55:
res[(ord(line[i]) - 65)] += 1
for i in range(26):
print(chr(65 + i) + " occurs %d times in the encrypted text" %(res[i]))
f3.close()
f1 = open("clearText.txt", "r")
lines = f1.readlines()
f2 = open("encryptedText.txt", "w")
for line in lines:
f2.write(encrypt(line, 3) + "\n")
f2.close()
f1.close()
frequency()