2022年2月11日金曜日

LINEダッシュボタン、Windows版暗号化プログラム他

1. フォトリフレクタ固定治具


3Dプリンタの印刷完了を検知するためのフォトリフレクタを3Dプリンタに固定するための部品を3Dプリンタで作りました。一度試作して2度目でfixです。


ステッピングモータに被せて固定します。PLAのため熱が心配なので稼働中のステッピングモータを触ってみましたがほんのり温かい程度だったので大丈夫かと思います。

窪みにフォトリフレクタとLEDの電流制限抵抗、プルアップ抵抗を載せたユニバーサル基板を組み込み、ホットボンドで埋めました。前回の試作段階ではコネクタを使ってしましたが、大きくなるのでコネクタは使用せず、2芯のシールド線で電源供給と信号を取り出します。

3Dプリンタ後ろのステッピングモータに被せた様子。ちょっときつかったので、ドライヤで温めて押し込みました。PLAは室温では固いので無理に入れると割れる。


印刷が完了すると、右上に少し見えているヒートベッドが移動してフォトリフレクタの上に来ます。それをトリガにして、LINEダッシュボタンが印刷完了メッセージを送る仕掛けです。

2.消費電力測定


ESP32のsleepしない版とsleep版の消費電力(電流)を計測しました。

・sleepせず、loop内でGPIOがlowになるのを検出する版:約80mA
・light sleepでGPIO変化をトリガとしてwakeupする版:約20mA (意外に大きい)

ACアダプタで5Vを供給したときの5Vの電流を測定(基板が完成していたので、3.3Vの測定はできず)。このため3.3Vに落とすための3端子レギュレータのロスも含まれます。また、LED消灯、フォトリフレクタ消灯、WiFi未接続、microSDは接続状態です。

sleep版も意外と消費電力が大きいのは、3端子レギュレータのロスがそんなに大きいのか、sleepの使い方が悪いのか、WiFiが完全にオフになってないのか。まあ、ACアダプタ動作なのでそんなに気にしなくてもよいのですが気になる。

3. Windows版暗号化プログラム


microSDに格納するアクセスポイントのSSID、パスワード、LINE notifyのトークンを暗号化するプログラムをWindows上で動くようにしました。

まず、平文のsetup.txtファイルを用意します。文字コードはUTF-8です(Arduino-IDEがUTF-8なので)。Windows10のメモ帳はデフォルトでUTF-8のようです。
1~3行目が秘密にしたいアクセスポイント名やパスワード、LINE notifyのトークンです。4行目が起動時にポストするメッセージ、5行目がボタンを押したりするイベント発生時にポストするメッセージです。



日本語を含む場合には、ターミナルをUTF-8にしておかないと文字化けします。あらかじめ、文字コード設定コマンド chcp 65001 を実行しておきます。


ターミナル(コマンドプロンプト)から、後述のencryptソースをコンパイルしたencryptコマンドを実行します。引数は、秘密の鍵、平文のテキストファイル名です。 秘密の鍵はESP32のスケッチ内に記載したものと一致させる必要があります。

ターミナルには、暗号化した文字列と、念のため復号化した文字列、および4行目以降が表示されます。

暗号化したテキストファイルが、元のファイル名の後ろに _crypt.txt を付けたファイル名で作成されます。このファイルを setup.txt にリネームして、microSDのルートディレクトリに格納します。


暗号化プログラムのソースです。ESP32用の暗号化・復号化スケッチ に main だけ追加したものです。エラーチェックや文字長チェックなどちゃんとしていません。無保証です。

プログラムにバグがあったので修正しました('22.2.13)。
//----------------------------------------------------------------------
//  '22.02.13 bug fix
//----------------------------------------------------------------------
#include <stdio.h>
#include <string.h>

void encrypt( char*a, char*b, char* key) {
  char x[128];
  int i,j,k,m;
  k = 0;
  int n = strlen(key);
  for (i=0; b[i]!=0; i++) {
    x[i] = b[i]^key[k++];
    k %= n;
  }
  m = i;

  // 8bit -> 6bit
  // 8bit           0          1          2
  //        000000|00, 0000|0000, 00|000000
  // 6bit        0        1        2      3
  j = 0;
  for (i=0; i<m; j++) {
    switch (j%4) {
      case 0:
        a[j] = (x[i]&0xFC)>>2;
        break;
      case 1:
        a[j] = (x[i]&0x03)<<4 | (x[i+1]&0xF0)>>4; 
        i++;
        break;
      case 2:
        a[j] = (x[i]&0x0F)<<2 | (x[i+1]&0xC0)>>6; 
        i++;
        break;
      case 3:
        a[j] = x[i]&0x3F;
        i++; 
        break;
    }
  }

  // ascii文字に変換
  for (i=0; i<j; i++) {
    a[i] += (int)'#';
  }
  a[i] = 0;
  
}

void decrypt( char*a, char*b, char* key) {
  char x[128];
  int i,j,k,m;
  // ascii文字をbinaryに戻す
  for(i=0; b[i]!=0; i++) {
    x[i] = b[i] - (int)'#';
  }
  m = i - 1;

  // 6bit -> 8bit
  j = 0;
  for(i=0; j<m ; i++) {
    switch (i%3) {
      case 0:
        a[i] = (x[j]&0x3F)<<2 | (x[j+1]&0x30)>>4;
        j++;
        break;
      case 1:
        a[i] = (x[j]&0x0F)<<4 | (x[j+1]&0x3C)>>2; 
        j++;
        break;
      case 2:
        a[i] = (x[j]&0x03)<<6 | (x[j+1]&0x3F);
        j += 2;
        break;
    }
  }
  m = i;
  
  k = 0;
  int n = strlen(key);
  for (i=0; i<m; i++) {
    a[i] ^= key[k++];
    k %= n;
  }
  a[i]= 0;
}

int main(int argc, char *argv[]) {
  int i;
  if (argc!=3) {
    printf("Usage: encrypt.exe key_text file_name\n");
    return(0);
  }
  char* key  = argv[1];
  char* file = argv[2];
  char  cryptfile[128];
  strcpy(cryptfile,file);
  strcat(cryptfile,"_crypt.txt");

  FILE *fp = fopen(file,"r");
  if (!fp) {
    printf("input file open error. %s\n",file);
    return(-1);
  }

  FILE *cfp = fopen(cryptfile,"w");
  if (!cfp) {
    printf("output file open error. %s\n",cryptfile);
    return(-1);
  }

  char plain_text[128];
  char encrypted[256];
  char decrypted[256];

  for (i=0;i<3;i++) {
    fgets(plain_text,128,fp);
    strtok(plain_text,"\n\0");
    encrypt(encrypted,plain_text,key);
    fprintf(cfp,"%s\n",encrypted);
    printf("encrypted:%s\n",encrypted);

    decrypt(decrypted,encrypted,key);
    printf("decrypted:%s",decrypted);
  }
  while( fgets(plain_text,128,fp) ) {
    printf("plaintext:%s",plain_text);
    fprintf(cfp,"%s",plain_text);
  }
  
  fclose(cfp);
  fclose(fp);
  printf("\nencrypted file : %s\n",cryptfile);

}

旧?ボーランドのBCCコンパイラでコンパイルできました。個人利用は無償です。

ESP32の最終版スケッチは近日アップ予定。

0 件のコメント:

コメントを投稿