Оптимизация Datamatrix Штрих-кодирования сжатия данных

Я ищу несколько советов о том, как лучше всего обработать строку таким образом, чтобы получить наиболее сжатую версию, основанную на кодировании в штрих-код матрицы данных.

Вот ссылка: https://en.wikipedia.org/wiki/Data_Matrix

Вот HTML-таблица коэффициентов сжатия (запустите фрагмент, чтобы увидеть таблицу):

<table border="1" align="center" bgcolor="#00CCFF">
  <tbody>
    <tr>
      <td>
        <p align="center"><b><i><font size="2">Compaction mode</font></i></b></p>
      </td>
      <td>
        <p align="center"><b><i><font size="2">Datas to encode</font></i></b></p>
      </td>
      <td>
        <p align="center"><b><i><font size="2">Rate compaction</font></i></b></p>
      </td>
    </tr>
    <tr>
      <td>
        <p><b><font size="2">ASCII</font></b></p>
      </td>
      <td>
        <p><b><font size="2">ASCII character 0 to 127</font></b></p>
      </td>
      <td>
        <p align="center"><b><font size="2">1 byte per CW</font></b></p>
      </td>
    </tr>
    <tr>
      <td>
        <p><b><font size="2">ASCII extended</font></b></p>
      </td>
      <td>
        <p><b><font size="2">ASCII character 128 to 255</font></b></p>
      </td>
      <td>
        <p align="center"><b><font size="2">0.5 byte&nbsp;per CW</font></b></p>
      </td>
    </tr>
    <tr>
      <td>
        <p><b><font size="2">ASCII numeric</font></b></p>
      </td>
      <td>
        <p><b><font size="2">ASCII digits</font></b></p>
      </td>
      <td>
        <p align="center"><b><font size="2">2 bytes per CW</font></b></p>
      </td>
    </tr>
    <tr>
      <td>
        <p><b><font size="2">C40</font></b></p>
      </td>
      <td>
        <p><b><font size="2">Upper-case alphanumeric</font></b></p>
      </td>
      <td>
        <p align="center"><b><font size="2">1.5 bytes per CW</font></b></p>
      </td>
    </tr>
    <tr>
      <td>
        <p><b><font size="2">TEXT</font></b></p>
      </td>
      <td>
        <p><b><font size="2">Lower-case alphanumeric</font></b></p>
      </td>
      <td>
        <p align="center"><b><font size="2">1.5 bytes&nbsp;per CW</font></b></p>
      </td>
    </tr>
    <tr>
      <td>
        <p><b><font size="2">X12</font></b></p>
      </td>
      <td>
        <p><b><font size="2">ANSI X12</font></b></p>
      </td>
      <td>
        <p align="center"><b><font size="2">1.5 bytes per CW</font></b></p>
      </td>
    </tr>
    <tr>
      <td>
        <p><b><font size="2">EDIFACT</font></b></p>
      </td>
      <td>
        <p><b><font size="2">ASCII character 32 to 94</font></b></p>
      </td>
      <td>
        <p align="center"><b><font size="2">1.33 &nbsp;bytes per CW</font></b></p>
      </td>
    </tr>
    <tr>
      <td>
        <p><b><font size="2">BASE 256</font></b></p>
      </td>
      <td>
        <p><b><font size="2">ASCII character 0 to 255</font></b></p>
      </td>
      <td>
        <p align="center"><b><font size="2">1 byte per CW</font></b></p>
      </td>
    </tr>
  </tbody>
</table>

Вот некоторые из факторов:

  • ASCII - это стандартный метод кодирования. 1 байт на символ
  • Последовательные числа сжимают больше всего. Конкретно номерные пары. 2 цифры на байт
  • Затем C40 Compression, 3 символа в 2 байта.
  • C40 стоит ОДИН байт переключения для активации режима кодирования C40.
  • C40 иногда стоит байта, чтобы переключиться обратно (или отменить) в режим кодирования ASCII
  • C40 требует дополнительного байта для кодирования "расширенного" символа (не буквенно-цифрового).

Мой первый метод состоял в том, чтобы пройти строку, чтобы быть закодированным символ за символом. Он возвращает список, а затем этот список обрабатывается, и строка кодируется соответствующим образом.

public static List<object[]> C40EncodingMap(string message)
        {
            int j = 0;
            bool c40Candidate = false;
            bool asciiCandidate = false;
            List<object[]> map = new List<object[]>();
            for (int i = 0; i < message.Length; i++)
            {
                c40Candidate = false;
                asciiCandidate = false;
                j = 0;
                char c = message[i];

                if (Char.IsLetterOrDigit(c) || Char.IsSeparator(c))
                {
                    while (Char.IsLetterOrDigit(c) || Char.IsSeparator(c))
                    {
                        //begin letters
                        c40Candidate = true;
                        j++;
                        if (i + j == message.Length) { break; }
                        c = message[i + j];
                    }
                }
                else if (Char.IsControl(c) || Char.IsSymbol(c) || Char.IsPunctuation(c))
                {
                    while (Char.IsControl(c) || Char.IsSymbol(c) || Char.IsPunctuation(c))
                    {
                        //begin char/shift chars
                        asciiCandidate = true;
                        j++;
                        if (i + j == message.Length) { break; }
                        c = message[i + j];
                    }
                }

                if (j > 0)
                {
                    if (c40Candidate)
                    {
                        if (j >= 5)//must be greater than 5 to make it worth while
                        {
                            //add logic for numbers greater than 
                            if (!ContainsNumbersGreaterThan(message.Substring(i, j), 4))
                                map.Add(new object[] { i, j, EncodingMethod.C40 });
                            else
                                asciiCandidate = true;
                        }
                        else
                            asciiCandidate = true;
                    }

                    if (asciiCandidate)
                    {
                        map.Add(new object[] { i, j, EncodingMethod.ASCII });
                    }
                }
                //Console.OutputEncoding = System.Text.Encoding.UTF8;//doesn't work
                Console.WriteLine(message.Substring(i, j)+"|");
                i += j-1;
            }

            return map;
        }


private static bool ContainsNumbersGreaterThan(string substring, int length)
{
    string comp = @"([0-9]{" + length.ToString() +",})";
    System.Text.RegularExpressions.Regex reg = new System.Text.RegularExpressions.Regex(comp);
    return reg.IsMatch(substring);
}

Вопрос:

Как мне лучше всего проанализировать заданную входную строку без набора спагетти-кода if-thens, чтобы получить наиболее компактную версию моего ввода?

Есть ли способ лучше? Посмотрите таблицы? Есть ли лучшие объекты (списки / коллекции, стеки) для управления? Набор уравнений или некоторые отношения?

Например, я могу найти раздел данных, который является "хорошим" кандидатом для кодирования C40, но он может содержать фрагмент последовательных чисел посередине, я хотел бы иметь возможность идентифицировать этот фрагмент, определить, является ли он Стоит отменить C40 для переключения на ascii для кодирования чисел, а затем определить, стоит ли переключаться обратно на C40 для кодирования остальных. Или я просто сначала иду после последовательных числовых разделов?

0 ответов

Другие вопросы по тегам