public static byte[] ToBinary(string hex_string) { const string CODELIST_DIG = "0123456789ABCDEF"; var data = new byte[(hex_string.Length + 1) / 2]; var data_size = 0; var hex_data_value = (byte)0; var hex_data_exist = false; hex_string = hex_string.ToUpper(); foreach (var code in hex_string) { hex_data_value = (byte)((hex_data_value << 4) | CODELIST_DIG.IndexOf(code)); if (hex_data_exist) { data[data_size++] = hex_data_value; hex_data_value = 0; } hex_data_exist = !hex_data_exist; } if (hex_data_exist) { data[data_size] = hex_data_value; } return(data); }
public static string ParseCodeText(string text, bool parse_special_code) { const string CODELIST_DIG = "0123456789ABCDEF"; const char CODELIST_SPACE = ' '; // const string CODELIST_SPECIAL = "$*"; char[] CODE_TEXTBLOCK = { '\'', '\'' }; // 'xxx' char[] CODE_TYPEBLOCK = { '<', '>' }; // <xxx> var collector = new StringBuilder(text.Length * 2); var mode = ParseMode.HexData; var code_temp = char.MinValue; var hex_data_exist = false; var text_data_escape = false; var text_data_builder = new StringBuilder(); var text_data_encoder = Encoding.UTF8; foreach (var code in text) { switch (mode) { /* === デフォルトモード === */ case ParseMode.HexData: { if (code == CODE_TEXTBLOCK[0]) { /* --- テキスト解析モードに移行 --- */ mode = ParseMode.TextData; if (hex_data_exist) { collector.Append(CODELIST_DIG[0]); hex_data_exist = false; } } else if (code == CODE_TYPEBLOCK[0]) { /* --- 文字コード指定モードに移行 --- */ mode = ParseMode.CharCode; if (hex_data_exist) { collector.Append(CODELIST_DIG[0]); hex_data_exist = false; } } else { /* --- 16進文字列を解析 --- */ /* 常に大文字で処理 */ code_temp = char.ToUpper(code); /* 16進文字列かどうかをチェック */ if (CODELIST_DIG.Contains(code_temp)) { hex_data_exist = !hex_data_exist; collector.Append(code_temp); } else if (code == CODELIST_SPACE) { /* --- 空白文字 --- */ hex_data_exist = false; } else if ((parse_special_code) && (CODELIST_SPECIAL.Contains(code_temp))) { /* 特殊文字を許可するかどうか */ collector.Append(code_temp); } else { /* --- 解析不能コード --- */ return(null); } } } break; case ParseMode.TextData: { if ((!text_data_escape) && (code == '\\')) { /* --- エスケープシーケンス --- */ text_data_escape = true; } else if ((!text_data_escape) && (code == CODE_TEXTBLOCK[1])) { /* --- バイナリ解析モードへ移行 --- */ if (text_data_builder.Length > 0) { foreach (var byte_text in text_data_encoder.GetBytes(text_data_builder.ToString())) { collector.Append(byte_text.ToString("X2")); } text_data_builder.Clear(); } mode = ParseMode.HexData; /* --- 特殊文字収集 --- */ } else if (text_data_escape) { switch (code) { case 'n': text_data_builder.Append('\n'); break; default: text_data_builder.Append(code); break; } text_data_escape = false; } else { /* --- 通常文字収集 --- */ text_data_builder.Append(code); } } break; case ParseMode.CharCode: { if (code == CODE_TYPEBLOCK[1]) { /* --- バイナリ解析モードへ移行 --- */ if (text_data_builder.Length > 0) { try { text_data_encoder = Encoding.GetEncoding(text_data_builder.ToString()); } catch { return(null); } text_data_builder.Clear(); } mode = ParseMode.HexData; } else { /* --- 文字収集 --- */ text_data_builder.Append(code); } } break; } } /* 16進モード以外で終了した場合はエラー */ if (mode != ParseMode.HexData) { return(null); } /* 最終データ収集 */ if (hex_data_exist) { collector.Append(CODELIST_DIG[0]); } return(collector.ToString()); }
public static byte[][] ToByteArrayMap(string text) { if (text == null) { return(null); } const string CODELIST_DIG = "0123456789ABCDEF"; const char CODELIST_SPACE = ' '; // const char CODELIST_SPARATOR = '|'; char[] CODE_TEXTBLOCK = { '\'', '\'' }; // 'xxx' char[] CODE_TYPEBLOCK = { '<', '>' }; // <xxx> var data_map = new Queue <byte[]>(); var data_buffer = new List <byte>(); var mode = ParseMode.HexData; var code_temp = char.MinValue; var hex_data_value = (byte)0; var hex_data_exist = false; var text_data_escape = false; var text_data_builder = new StringBuilder(); var text_data_encoder = Encoding.UTF8; foreach (var code in text) { switch (mode) { /* === デフォルトモード === */ case ParseMode.HexData: { if (code == CODELIST_SPARATOR) { /* --- 新しいデータに移行 --- */ if (data_buffer.Count > 0) { data_map.Enqueue(data_buffer.ToArray()); data_buffer = new List <byte>(); } } else if (code == CODE_TEXTBLOCK[0]) { /* --- テキスト解析モードに移行 --- */ mode = ParseMode.TextData; } else if (code == CODE_TYPEBLOCK[0]) { /* --- 文字コード指定モードに移行 --- */ mode = ParseMode.CharCode; } else { /* --- 16進文字列を解析 --- */ /* 常に大文字で処理 */ code_temp = char.ToUpper(code); /* 16進文字列かどうかをチェック */ if (CODELIST_DIG.Contains(code_temp)) { hex_data_value = (byte)(((hex_data_value << 4) & 0xF0) | (CODELIST_DIG.IndexOf(code_temp))); hex_data_exist = !hex_data_exist; /* 2バイト集まったら収集 */ if (!hex_data_exist) { data_buffer.Add(hex_data_value); hex_data_value = 0x00; } } else if (code == CODELIST_SPACE) { /* --- 空白文字 --- */ /* データが存在する場合は強制適用 */ if (hex_data_exist) { data_buffer.Add(hex_data_value); hex_data_value = 0x00; hex_data_exist = false; } } else { /* --- 解析不能コード --- */ return(null); } } } break; case ParseMode.TextData: { if ((!text_data_escape) && (code == '\\')) { /* --- エスケープシーケンス --- */ text_data_escape = true; } else if ((!text_data_escape) && (code == CODE_TEXTBLOCK[1])) { /* --- バイナリ解析モードへ移行 --- */ if (text_data_builder.Length > 0) { data_buffer.AddRange(text_data_encoder.GetBytes(text_data_builder.ToString())); text_data_builder.Clear(); } mode = ParseMode.HexData; /* --- 特殊文字収集 --- */ } else if (text_data_escape) { switch (code) { case 'n': text_data_builder.Append('\n'); break; default: text_data_builder.Append(code); break; } text_data_escape = false; } else { /* --- 文字収集 --- */ text_data_builder.Append(code); } } break; case ParseMode.CharCode: { if (code == CODE_TYPEBLOCK[1]) { /* --- バイナリ解析モードへ移行 --- */ if (text_data_builder.Length > 0) { try { text_data_encoder = Encoding.GetEncoding(text_data_builder.ToString()); } catch { return(null); } text_data_builder.Clear(); } mode = ParseMode.HexData; } else { /* --- 文字収集 --- */ text_data_builder.Append(code); } } break; } } /* 16進モード以外で終了した場合はエラー */ if (mode != ParseMode.HexData) { return(null); } /* 最終データ収集 */ if (hex_data_exist) { data_buffer.Add(hex_data_value); } /* 最後のデータをリストに追加 */ if (data_buffer.Count > 0) { data_map.Enqueue(data_buffer.ToArray()); } return(data_map.ToArray()); }