单片机结课项目记录 +Python基础结课项目 (纪念)

单片机部分

在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

  1. 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).
  2. 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).
  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)
  4. 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()

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值