Оптимизация 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 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 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 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 для кодирования остальных. Или я просто сначала иду после последовательных числовых разделов?