// Copyright (C) 2017 Marius Schellenberger #include #include #include #include #include #include /* Display GND (Display) -> GND (Arduino UNO) VCC (Display) -> 5V (Arduino UNO) SDA (Display) -> A4 (Arduino UNO) SCL (Display) -> A5 (Arduino UNO) */ // control #define TRUE 1 #define D8 8 #define D9 9 #define D10 10 #define D11 11 #define D12 12 int b1, b2, b3, b4, b5; void read_b(void) { b1 = digitalRead(D12); b2 = digitalRead(D11); b3 = digitalRead(D10); b4 = digitalRead(D9); b5 = digitalRead(D8); } // data #define ALPHA_MAX 36 char _itoa[ALPHA_MAX]; int _atoi[91]; void cont(void) { while (digitalRead(D8) != HIGH); delay(200); } void init_itoa(void) { for (int i = 0; i < 10; i++) _itoa[i] = (char)48 + i; for (int i = 10; i < ALPHA_MAX; i++) _itoa[i] = (char)55 + i; } void init_atoi(void) { int c = 0; for (int i = 48; i < 58; i++) _atoi[i] = c++; for (int i = 65; i < 91; i++) _atoi[i] = c++; } // random #define CHAR_MAX 256 const unsigned char _r_max = CHAR_MAX - (CHAR_MAX % ALPHA_MAX); volatile unsigned char _r_sample = 0; volatile char _r_new = 0; unsigned char _r = 0; ISR(WDT_vect) { _r_sample = TCNT1L; _r_new = 1; } void _r_init(void) { cli(); MCUSR = 0; WDTCSR |= _BV(WDCE) | _BV(WDE); WDTCSR = _BV(WDIE); sei(); } char _r_rotl_one(const char v) { int shift = 1; if ((shift &= sizeof(v) * 8 - 1) == 0) return v; return (v << shift) | (v >> (sizeof(v) * 8 - shift)); } char _r_char(void) { char i = 0; while (TRUE) { if (_r_new) { _r_new = 0; _r = _r_rotl_one(_r); _r ^= _r_sample; if (i++ > 7) { if (_r < _r_max) return _itoa[_r % ALPHA_MAX]; else i = 0; } } } } // LCD #define COLS 20 #define ROWS 4 #define WS ' ' #define NULL_CHAR '\0'; LiquidCrystal_I2C lcd(0x27, COLS, ROWS); void clr_all(void) { for (int r = 0; r < ROWS; r++) clr(r); } void clr(const int row) { for (int c = 0; c < COLS; c++) { lcd.setCursor(c, row); lcd.print(WS); } } void prntl(const int row, const char *str) { int len = strlen(str); for (int i = 0; i < len; i++) prntc(row, i, str[i]); while (len < COLS) prntc(row, len++, WS); } void prntlong(int row, const char *str) { clr_all(); int c = 0; for (int i = 0; i < strlen(str); i++) { prntc(row, c++, str[i]); if (i == (COLS - 1) || i == ((COLS * 2) - 1) || i == ((COLS * 3) - 1)) { row++; c = 0; } } } void prntstr(const int row, const int col, const int len, const char *str) { for (int i = 0; i < len; i++) prntc(row, col+i, str[i]); } void prntc(const int row, const int col, const char c) { lcd.setCursor(col, row); lcd.print(c); } void prnti(const int row, const int col, const int i) { char buf[10]; itoa(i, buf, 10); prntstr(row, col, strlen(buf), buf); } // char ops char add_ten(char c) { for (int i = 0; i < 10; i++) c = add_one(c); return c; } char add_one(const char c) { int n = (int)c + 1; if (n == 91) return '0'; if (n == 64) return '9'; if (n == 58) return 'A'; if (n == 47) return 'Z'; return (char)n; } char sub_ten(char c) { for (int i = 0; i < 10; i++) c = sub_one(c); return c; } char sub_one(const char c) { int n = (int)c - 1; if (n == 91) return '0'; if (n == 64) return '9'; if (n == 58) return 'A'; if (n == 47) return 'Z'; return (char)n; } // crypto char *keygen(const int len) { char *key = (char*)malloc(sizeof(char) * (len + 1)); for (int i = 0; i < len; i++) key[i] = _r_char(); key[len] = NULL_CHAR; return key; } char *encrypt(const char *txt, const char *key) { int i = 0, c = 0; int len = strlen(key); char *enc = (char*)malloc(sizeof(char) * (len + 1)); while (*txt) { c = _atoi[(int)*txt++] + _atoi[(int)*key++]; if (c > 36) { c -= 36; } enc[i++] = _itoa[c]; } enc[len] = NULL_CHAR; return enc; } char *decrypt(const char *enc, const char *key) { int i = 0, c = 0; int len = strlen(key); char *txt = (char*)malloc(sizeof(char) * (len + 1)); while (*enc) { c = _atoi[(int)*enc++] - _atoi[(int)*key++]; if (c < 0) { c += 36; } txt[i++] = _itoa[c]; } txt[len] = NULL_CHAR; return txt; } void enc_test(void) { char txt[] = "0ZYX"; char key[] = "EU16"; char *enc = encrypt(txt, key); clr_all(); prntl(0, "Encrypt Test"); prntl(2, enc); prntl(3, "ETZ3"); free(enc); cont(); } void dec_test(void) { char enc[] = "KU69"; char key[] = "AJU9"; char *dec = decrypt(enc, key); clr_all(); prntl(0, "Decrypt Test"); prntl(2, dec); prntl(3, "ABC0"); free(dec); cont(); } char *input(void) { char p = 0, in = 'A'; int row = 0, col = 0, c = 0; int len = COLS; char *buf = (char*)malloc(sizeof(char) * len); prntc(row, col, in); while (TRUE) { read_b(); if (b1 == HIGH) { delay(100); if (b2 == HIGH) { prntc(row, col--, WS); if (c > 0) c--; if (row > 0 && col < 0) { row--; col = (COLS - 1); } in = 'A'; delay(300); } } if (b3 == HIGH) { delay(100); if (b4 == HIGH) { prntc(row, col, WS); buf = (char*)realloc(buf, sizeof(char) * c); buf[c] = NULL_CHAR; return buf; } } if (b5 == HIGH) { if (col == COLS || col == (COLS * 2) || col == (COLS * 3)) { row++; col = 0; } prntc(row, col++, in); buf[c++] = in; if (c == len) { len += COLS; buf = (char*)realloc(buf, sizeof(char) * len); } delay(300); } if (b1 == HIGH) { in = sub_ten(in); p = 1; } if (b2 == HIGH) { in = sub_one(in); p = 1; } if (b3 == HIGH) { in = add_one(in); p = 1; } if (b4 == HIGH) { in = add_ten(in); p = 1; } if (p) { p = 0; prntc(row, col, in); delay(200); } } } void enc_mode(void) { clr_all(); char *txt, *key, *enc; txt = input(); key = keygen(strlen(txt)); enc = encrypt(txt, key); prntlong(0, key); cont(); prntlong(0, enc); free(txt); free(key); free(enc); cont(); } void dec_mode(void) { clr_all(); int len = 0; char *enc, *key, *dec; enc = input(); clr_all(); key = input(); dec = decrypt(enc, key); prntlong(0, dec); free(enc); free(key); free(dec); cont(); } void key_mode(void) { clr_all(); char p = 0; char *key; int len = COLS * 2; prnti(0, 0, len); while (TRUE) { read_b(); if (b1 == HIGH && len > 10) { len -= 10; p = 1; } if (b2 == HIGH && len > 1) { len--; p = 1; } if (b3 == HIGH && len < (COLS * ROWS)) { len++; p = 1; } if (b4 == HIGH && len <= ((COLS * ROWS) - 10)) { len += 10; p = 1; } if (p) { p = 0; prntl(0, ""); prnti(0, 0, len); delay(150); } if (b5 == HIGH) break; } key = keygen(len); prntlong(0, key); free(key); cont(); } void setup(void) { pinMode(D8, INPUT); pinMode(D9, INPUT); pinMode(D10, INPUT); pinMode(D11, INPUT); pinMode(D12, INPUT); _r_init(); lcd.init(); lcd.backlight(); lcd.setCursor(0, 0); init_atoi(); init_itoa(); } void loop(void) { clr_all(); prntl(0, "Encrypt: 1 KeyGen: 5"); prntl(1, "Decrypt: 2"); prntl(2, "Encrypt Test: 3"); prntl(3, "Decrypt Test: 4"); while (TRUE) { read_b(); if (b1 == HIGH) { enc_mode(); break; } if (b2 == HIGH) { dec_mode(); break; } if (b3 == HIGH) { enc_test(); break; } if (b4 == HIGH) { dec_test(); break; } if (b5 == HIGH) { key_mode(); break; } } }