/// <summary> /// liefert den Text, der ev. <see cref="SpecialChars"/> enthält /// </summary> /// <param name="data"></param> /// <param name="start">Startindex der Decodierung</param> /// <param name="bytesconsumed">Anzahl der verwendeten Bytes</param> /// <returns></returns> string Decode6(byte[] data, int start, out int bytesconsumed) { bytesconsumed = 0; string text = ""; Queue <bool> bits = new Queue <bool>(); SpecialCodes6Bit spec = SpecialCodes6Bit.nothing; bool end = false; do { byte code6 = 0x00; if (bits.Count < 2) { Byte2BitQueue(data[start++], bits); bytesconsumed++; } code6 = PushBit(code6, bits.Dequeue()); code6 = PushBit(code6, bits.Dequeue()); if (code6 != 0x03) // keine Endekennung 11xxxx { if (bits.Count < 4) { Byte2BitQueue(data[start++], bits); bytesconsumed++; } for (int j = 0; j < 4; j++) { code6 = PushBit(code6, bits.Dequeue()); } switch (spec) { case SpecialCodes6Bit.NextIsSymbol: case SpecialCodes6Bit.NextIsLower: text += spec == SpecialCodes6Bit.NextIsSymbol ? SymbolTable6Bit[code6] : LowerTable6Bit[code6]; spec = SpecialCodes6Bit.nothing; break; default: switch (code6) { case (int)SpecialCodes6Bit.NextIsSymbol: case (int)SpecialCodes6Bit.NextIsLower: spec = (SpecialCodes6Bit)code6; break; case (int)SpecialCodes6Bit.Delimiter: case (int)SpecialCodes6Bit.HideFollowingAndInsertSpace: case (int)SpecialCodes6Bit.HidePrecedingAndInsertSpace: case (int)SpecialCodes6Bit.SymbolCanadianHighwayBlackWhite: case (int)SpecialCodes6Bit.SymbolCanadianHighwayBlueRed: case (int)SpecialCodes6Bit.SymbolHighway: case (int)SpecialCodes6Bit.SymbolHighwaySmallWhite: case (int)SpecialCodes6Bit.SymbolInterstate: case (int)SpecialCodes6Bit.SymbolStateHighway: text += SpecialChars[(SpecialCodes)code6]; break; default: text += CodeTable6Bit[code6 & 0x3f]; break; } break; } } else { end = true; } } while (!end); return(text); }
/// <summary> /// liefert den Text, der ev. <see cref="SpecialChars"/> enthält /// </summary> /// <param name="data"></param> /// <param name="start">Startindex der Decodierung</param> /// <param name="bytesconsumed">Anzahl der verwendeten Bytes</param> /// <returns></returns> string Decode6x(byte[] data, int start, out int bytesconsumed) { string text = ""; bytesconsumed = 0; SpecialCodes6Bit spec = SpecialCodes6Bit.nothing; List <bool> bit = new List <bool>(); bool end = false; for (int i = start; i < data.Length && !end; i++) { // alle 8 Bits jedes Bytes in die Bit-Liste schieben byte b = data[i]; bytesconsumed++; for (int j = 0; j < 8; j++) { bit.Add((b & 0x80) != 0); b <<= 1; } // wenn die akt. Bitliste min. 6 Bit lang ist, kann wieder dekodiert werden while (bit.Count >= 6) // nächstes Zeichen dekodieren { int code6 = 0x00; for (int j = 0; j < 6; j++) // 6 Bits aus der Bitliste holen { if (bit[0]) { code6 |= 0x01; } if (j < 5) { code6 <<= 1; } bit.RemoveAt(0); // Bit aus der Bitliste entfernen } if (code6 > 0x2f) // Ende // Skip until the next byte boundary. Note that may mean that we skip more or *less* than 6 bits. { bit.Clear(); end = true; break; } switch (spec) { case SpecialCodes6Bit.NextIsSymbol: text += SymbolTable6Bit[code6 & 0x3f]; spec = SpecialCodes6Bit.nothing; break; case SpecialCodes6Bit.NextIsLower: text += LowerTable6Bit[code6 & 0x3f]; spec = SpecialCodes6Bit.nothing; break; default: switch (code6 & 0x3f) { case (int)SpecialCodes6Bit.NextIsSymbol: spec = SpecialCodes6Bit.NextIsSymbol; break; case (int)SpecialCodes6Bit.NextIsLower: spec = SpecialCodes6Bit.NextIsLower; break; case (int)SpecialCodes6Bit.Delimiter: text += SpecialChars[SpecialCodes.Delimiter]; break; case (int)SpecialCodes6Bit.HideFollowingAndInsertSpace: text += SpecialChars[SpecialCodes.HideFollowingAndInsertSpace]; break; case (int)SpecialCodes6Bit.HidePrecedingAndInsertSpace: text += SpecialChars[SpecialCodes.HidePrecedingAndInsertSpace]; break; case (int)SpecialCodes6Bit.SymbolCanadianHighwayBlackWhite: text += SpecialChars[SpecialCodes.SymbolCanadianHighwayBlackWhite]; break; case (int)SpecialCodes6Bit.SymbolCanadianHighwayBlueRed: text += SpecialChars[SpecialCodes.SymbolCanadianHighwayBlueRed]; break; case (int)SpecialCodes6Bit.SymbolHighway: text += SpecialChars[SpecialCodes.SymbolHighway]; break; case (int)SpecialCodes6Bit.SymbolHighwaySmallWhite: text += SpecialChars[SpecialCodes.SymbolHighwaySmallWhite]; break; case (int)SpecialCodes6Bit.SymbolInterstate: text += SpecialChars[SpecialCodes.SymbolInterstate]; break; case (int)SpecialCodes6Bit.SymbolStateHighway: text += SpecialChars[SpecialCodes.SymbolStateHighway]; break; default: text += CodeTable6Bit[code6 & 0x3f]; break; } break; } //if (code6 > 0x2f) { // i = txt.Length; // break; //} } } return(text); }
/// <summary> /// codiert den Text, der ev. <see cref="SpecialChars"/> enthält /// </summary> /// <param name="txt"></param> /// <returns></returns> byte[] Encode6(string txt) { txt = Valid6BitChars.Replace(txt, "#").Trim(); // Text enthält nur noch gültige Zeichen für 6-Bit; ungültige Zeichen werden zu '#' List <bool> bit = new List <bool>(); for (int k = 0; k < txt.Length; k++) { char c = txt[k]; bool lastchar = k == txt.Length - 1; int code6 = -1; SpecialCodes6Bit spec = SpecialCodes6Bit.nothing; if (SpecialCode4Chars.ContainsKey(c)) { switch (SpecialCode4Chars[c]) { case SpecialCodes.SymbolCanadianHighwayBlackWhite: case SpecialCodes.SymbolCanadianHighwayBlueRed: case SpecialCodes.SymbolHighway: case SpecialCodes.SymbolHighwaySmallWhite: case SpecialCodes.SymbolInterstate: case SpecialCodes.SymbolStateHighway: case SpecialCodes.Delimiter: case SpecialCodes.HideFollowingAndInsertSpace: case SpecialCodes.HidePrecedingAndInsertSpace: code6 = (int)SpecialCode4Chars[c]; break; } } else { for (int i = 0; i < CodeTable6Bit.Length; i++) { if (CodeTable6Bit[i] == c) { spec = SpecialCodes6Bit.nothing; code6 = i; break; } } if (code6 < 0) { for (int i = 0; i < SymbolTable6Bit.Length; i++) { if (SymbolTable6Bit[i] == c) { spec = SpecialCodes6Bit.NextIsSymbol; code6 = i; break; } } } if (code6 < 0) { for (int i = 0; i < LowerTable6Bit.Length; i++) { if (LowerTable6Bit[i] == c) { spec = SpecialCodes6Bit.NextIsLower; code6 = i; break; } } } } if (lastchar) { if (code6 < 0) { code6 = 0; } code6 |= 0x30; // Endekennung gesetzt (Bit 4 und 5) } if (code6 >= 0) { if (spec != SpecialCodes6Bit.nothing) { int code = (int)spec; // 6 Bits, beginnend mit Bit 0, in den Puffer schieben for (int i = 0; i < 6; i++) { bit.Add((code & 0x01) != 0); code >>= 1; } } // 6 Bits, beginnend mit Bit 0, in den Puffer schieben for (int i = 0; i < 6; i++) { bit.Add((code6 & 0x01) != 0); code6 >>= 1; } } } // Bit-Liste in Byte-Liste umrechnen List <byte> lst = new List <byte>(); byte b = 0x00; for (int i = 0; i < bit.Count; i++) { if (i % 8 == 0) // neues Byte { b = 0x00; } else { b <<= 1; } if (bit[i]) { b |= 0x81; // das niederwertigste Bit setzen } if (i % 8 == 7 || // Byte ist voll i == bit.Count - 1) // alle Bits verarbeitet { if (i % 8 != 7) { b <<= 7 - i % 8; // nach "oben" schieben } lst.Add(b); } } return(lst.ToArray()); }