山口屋~活動日誌~

私生活で主な出来事をピックアップ

メール 改行 76文字 SMTP MIME

2020-03-22 22:44:53 | パソコン
たまたま、Base64というエンコード方式を調べていたら、Multipurpose Internet Mail Extension(多目的インターネットメール拡張)の基準で「76文字毎に改行コード」という興味深い記述があった。調べてみたところ、下記が根拠らしい。

●RFC 1521 :MIME (Multipurpose Internet Mail Extensions)
〇Appendix B 「符号化したデータの行は、76文字を超えてはならない」

この他にも下記のものが存在する。

●RFC 821:Simple Mail Transfer Protocol
〇4.5.3に「CRLFを含めて1000文字まで」
→RFC 5321:Simple Mail Transfer Protocol
〇「CRLFを含むテキスト行の最大長は1000オクテット」

●RFC 2822:Internet Message Format
〇「文字列は998以下の文字でなければならず、CRLFを除いて78文字であるべき」
・メール技術がUS-ASCIIで7bit処理だった頃の名残を含む。
・998以下の文字:データ転送上の限界として、1 行のデータの長さは最大で(US-ASCII で)1000 文字以内、CRLFを除いて998文字。
・CRLFを除いて78文字:MUA(Mail User Agent)における表示上の問題に配慮。
→RFC 5322
・US-ASCIIを使用する。

US-ASCIIでは78文字だが、US-ASCII以外は変換をするため76文字となる。
コメント
  • Twitterでシェアする
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

文字コード マルチバイト文字 ワイド文字 char wchar_t C言語 C++/CLI C# mblen

2020-03-21 23:21:29 | ソフトウェア開発
<文字コード>

●1byte文字コード
○ASCII(7bit)
→ISO/IEC 646(7bit)
→ASCII(一部異なる)(7bit)+片仮名など(7bit):JIS X 0201

●2byte文字コード、符号化方式(可変長、マルチバイト文字)
○ISO/IEC 2022
→JIS X 0208
○JIS X 0208の符号化方式
→ASCII(1byte)を同時使用:EUC-JP(後述)
→JIS X 0201(1byte)を同時使用:Shift-JIS(後述)

●ワイド文字コードと符号化方式
○Unicode(16bit=2byte):UCS-2(固定長)
○ISO/IEC 10646(4byte)、JIS X 0221:UCS-4(固定長)
→Unicodeとの互換、UCS-2の拡張:UTF-16(注:サロゲート含む、2byteとは限らない)
→ASCIIとの互換:UTF-8(注:マルチバイト文字コード)
※UCS:Universal multi-octet coded Character Set
※UTF:UCS Transformation Format

<文字符号化方式>

●EUC-JP
※EUC:Extended Unix Code
○ASCII(1byte)は第8ビットが0、JIS X 0208等は第8ビットが1(第2バイト以降でも)。
・第1バイトが0x80未満であれば1バイト文字:ASCII
・第1バイトが0x80以上0x8E未満(0x8D)であれば2バイト文字:JIS X 0208
・第1バイトが0x8Eであれば2バイト文字:JIS X 0201
・第1バイトが0x8F以上(0x8F)であれば3バイト文字:JIS X 0212。

●Shift-JIS
・Windows メモ帳 では ANSI
○第8ビットを含め、JIS X 0201が使用しない部分にJIS X 0208を割り当て。
・第1バイトが0x81~0x9F、0xE0~0xEF(Windows-31J:0xFC)であれば2バイト文字。第2バイトは0x40~0x7E、0x80~0xFC。
・第2バイトを1バイト文字と見なすと、ASCIIやJIS X 0201で割り当てのある領域なので注意。

●UTF-16
・以前のWindows メモ帳 では Unicode
○UCS-2の拡張、UCS-2で文字の割り当てのない領域をサロゲートとして利用。
→サロゲートは、UCS-4にあるUCS-2に収まらなかった部分を示す。
○ビッグエンディアンとリトルエンディアン

●UTF-8
・Windows 10 ver.1903以降 メモ帳 のデフォルト保存形式、BOM無。
・Excel 2016 以降 CSVファイルの保存形式で選択可能、BOM有らしい。
○ASCII(1byte)は第8ビットが0、それ以外は第8ビットが1(第2バイト以降でも)。
・0x00以上0x7F以下(0b0xxxxxxx)であれば第1バイト、1バイト文字。
・0x80以上0xBF以下(0b10xxxxxx)であれば第2バイト以降。(RFC3629:2003では一部変更)
・0xc0以上0xDF以下(0b110xxxxx)であれば第1バイト、2バイト文字。
・0xe0以上0xEF以下(0b1110xxxx)であれば第1バイト、3バイト文字。
・0xF0以上0xF7以下(0b11110xxx)であれば第1バイト、4バイト文字。(RFC3629:2003では0xF4以下に変更)
・0xF8以上0xFB以下(0b111110xx)であれば第1バイト、5バイト文字。(RFC3629:2003では廃止)
・0xFC以上0xFD以下(0b1111110x)であれば第1バイト、6バイト文字。(RFC3629:2003では廃止)

<データ型>

●char型
・byte数は必ず1byte
・シングルバイト文字、マルチバイト文字:可変byte
・EUC-JP、Shift-JIS、UTF-8
・mblen関数:1文字のbyte数を調べるが、使用前にロケール設定が必要。

●wchar_t型
・byte数は処理系依存
・ワイド文字(UCS-2、UCS-4):固定byte
・UTF-16、UTF-32

<プログラムの文字コード>

ネイティブコード(C/C++):Windows-31J(Shift_JISベース)
マネージコード(C++/CLI,C#):Unicode(UTF-16)

//マネージコードの文字列をネイティブコードの文字列から作成
System::String^ ToCLI(std::string& input, System::Text::Encoding^ encoding)
{
 return gcnew System::String(
  input.data(),
  0,
  input.size(),
  encoding); // 変換元エンコーディング(ネイティブコード)
}
//ネイティブコードの文字列をマネージコードの文字列から作成
std::string FromCLI(String^ input, System::Text::Encoding^ encoding)
{
 std::string result;
 if ( input != nullptr && input->Length > 0 )
 {
  array<Byte>^ barray =
   System::Text::Encoding::Convert(
   Encoding::Unicode, // 変換元エンコーディング(マネージコード)
   encoding, // 変換先エンコーディング(ネイティブコード)
   Encoding::Unicode->GetBytes(input));
  pin_ptr<Byte> pin = &barray[0];
  result.assign(reinterpret_cast(pin), barray->Length);
 }
 return result;
}

C/C++ではWin32スタティック・ライブラリとして.libファイルを生成、C++/CLIでは.libファイルと.hファイルへの参照を追加して、C++クラスとの区別のためにrefキーワードを付けてC++/CLIクラスを定義し.NETダイナミック・ライブラリとして.dllファイルを生成することで、C#からC/C++を呼び出すことができるようになる。

C++/CLIのクラスでは、C関数であれは、static関数として定義し、C++クラスであれば、ネイティブコードのインスタンスを生成して代入するネイティブコードのポインタをメンバとして定義、ポインタに対する処理でメソッドを定義、ファイナライザを定義してデストラクタから呼出、というように記述する。

<参考書籍、参考URL>
UnicodeとUTF-8とUCS-2の関係-符号化文字集合? 文字符号化方式?

<参考URL>
charとUnicodeとワイド文字をごっちゃにしないために
UCSとUnicode
UCSとUTF
文字コードに関する覚え書きと実験
弘前学院聖愛中学高等学校:java プログラミング もくじ
RFC3629でUTF-8のバイト範囲が変更されている
Vista到来。既存C/C++資産の.NET化を始めよう! - @IT
コメント
  • Twitterでシェアする
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

C言語 ファイル 入出力 include ディレクティブ

2020-03-21 11:24:58 | ソフトウェア開発
C言語でファイル入出力関連の関数、マクロで代表的なものを以下に示す。

●ファイル入出力
#include
・FILE* fopen(const char* file, const char* mode)
・FILE* freopen(const char* file, const char* mode, FILE* fp)
・int fsetpos(FILE* fp, const fpos_t *position)
・int fgetpos(FILE* fp, fpos_t *position)
・int fclose(FILE* fp)

●エラー判定
#include
・int ferror(FILE* fp)
#include
・errnoマクロ

安全にファイル入出力を行おうとすると、いろいろ工夫が必要になる。
IPA ISEC セキュア・プログラミング講座(新版):ファイルレースコンディション対策
IPA ISEC セキュア・プログラミング講座(旧版):Windowsパス名の落とし穴

自作コンパイラでincludeディレクティブを実装する場合は以下を保持する必要がありそうだ。
・char* file
・fpos_t position
エラー出力用に入力中の行数、列数を保持するため、
・int row
・int column
さらに、ファイルのあるディレクトリが可変となるため、ルートディレクトリ、カレントディレクトリも別に保持する必要がありそうだ。

●文字列の比較、コピー、連結
#include
・char* strrchr(const char* string, int character)
・char* strncpy(char* string1, const char* string2, size_t n)
・char* strncat(char* string1, const char* string2, size_t n)
コメント
  • Twitterでシェアする
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする