using System.Collections;
using System.Runtime.Intrinsics.X86;
using System.Text;
namespace BarcodeLibrary;
///
/// Формат сборки штрих-кода, в отдельном файле
///
public enum BarcodeType
{
///
/// Текстовая информация
///
Text,
///
/// Штрих-код
///
Barcode,
///
/// Полная информация
///
Full
}
internal static class BarcodeHelper
{
#region Help
///
///
/// ████████████████████████████████████████████████████████████
/// ██ ▌█▐█▌█▌▐▐█ █▐▌▌█▐ ██ ▌ ▌▌▌█ █ █▐▐█▌▌▐▌██▐ ▐ ▌▐█ ▐▐ ██
/// ██ ▌█▐█▌█▌▐▐█ █▐▌▌█▐ ██ ▌ ▌▌▌█ █ █▐▐█▌▌▐▌██▐ ▐ ▌▐█ ▐▐ ██
/// ██ ▌█▐█▌█▌▐▐█ █▐▌▌█▐ ██ ▌ ▌▌▌█ █ █▐▐█▌▌▐▌██▐ ▐ ▌▐█ ▐▐ ██
/// ██ ▌█▐█▌█▌▐▐█ █▐▌▌█▐ ██ ▌ ▌▌▌█ █ █▐▐█▌▌▐▌██▐ ▐ ▌▐█ ▐▐ ██
/// ████████████████████████████████████████████████████████████
/// Example
///
///
public static string GetCode(string text)
{
bool CodeMode = CheckNumbers(text, 0, 4); // выбор режима
int index = 0; // индекс для прохода по символам текста
StringBuilder stringBuilder = new StringBuilder(Frame); // создание объекта для формирования строки штрих-кода, добавление рамки в начале
IList PatternNumbers = new List(); // список для хранения номеров паттернов
Add(stringBuilder, PatternNumbers, CodeMode ? StartNumbers : StartText); // добавление начального паттерна (в зависимости от режима)
while (index < text.Length) // проход по символам строки
{
CodeBuilder(text, stringBuilder, PatternNumbers, ref CodeMode, ref index); // обновление строки штрих-кода, добавление нового символа
}
Add(stringBuilder, PatternNumbers, ControlPattern(PatternNumbers)); // добавление контрольного паттерна
Add(stringBuilder, PatternNumbers, Stop); // добавление паттерна остановки
stringBuilder.Append(Frame); // добавление рамки в конце
var tmp = stringBuilder.ToString(); // преобразование строки штрих-кода в бинарный код
stringBuilder = new StringBuilder();
foreach (var i in tmp.SplitString(2)) // проход по каждой паре символов
{
stringBuilder.Append(Convertation(i)); // конвертация в символы штрихов
}
tmp = stringBuilder.ToString(); // строка с бинарным штрих-кодом
var tmp1 = string.Empty.PadRight(tmp.Length, Bars[0]); // строка с рамкой
stringBuilder = new StringBuilder();
stringBuilder.AppendLine(tmp1); // добавление верхней рамки
for (int i = 0; i < Height; i++) // добавление штрих-кода Height раз (чтобы он был высотой Height)
{
stringBuilder.AppendLine(tmp);
}
stringBuilder.AppendLine(tmp1); // добавление нижней рамки
return stringBuilder.ToString(); // возвращение итоговой строки со штрих-кодом
}
private static void CodeBuilder(string text, StringBuilder stringBuilder, IList PatternNumbers, ref bool CodeMode, ref int index)
{
if ((CodeMode && !CheckNumbers(text, index, 2)) || // проверка, нужно ли переключать режим
(!CodeMode && CheckNumbers(text, index, 4)))
{
CodeMode = !CodeMode; // переключение режима
Add(stringBuilder, PatternNumbers, CodeMode ? SwitchToNumbers : SwitchToText); // добавление кода смена режима
}
ModeBuilder(ref index, PatternNumbers, CodeMode, text, stringBuilder); // кодирование символа
}
private static void ModeBuilder(ref int index, IList PatternNumbers, bool CodeMode, string text, StringBuilder sb)
{
if (CodeMode) // Если числовой режим
{
Add(sb, PatternNumbers, Array.IndexOf(NumberSymbols, text.Substring(index, 2))); // Обрабатывается пара чисел
index += 2; // Индекс увеличивается на 2
}
else // Если символьный режим
{
Add(sb, PatternNumbers, Array.IndexOf(TextSymbols, text.Substring(index, 1))); // Обрабатывается 1 символ
index++; // Индекс увеличивается на 1
}
}
private static void Add(StringBuilder sb, IList PatternNumbers, int index)
{
sb.Append(Patterns[index]); // В StringBuilder добавляется паттерн по индексу
PatternNumbers.Add(index); // добавляется индекс паттерна в список линий
}
private static bool CheckNumbers(string text, int current, int qt) // проверка, являются ли символы цифрами
{
var chars = text.Skip(current).Take(qt);
return chars.Count() == qt && chars.All(x => char.IsDigit(x));
}
private static int ControlPattern(IList PatternNumbers) // Вычисление контрольной суммы
{
var sum = PatternNumbers[0]; // Сумма начинается с 1 элемента списка паттернов
for (var i = 1; i < PatternNumbers.Count; i++) // Затем индекс умножается на значение и добавляется в сумму
{
sum += i * PatternNumbers[i];
}
sum %= 103; // Контрольная сумма делится по модулю на 103
return sum; // Возврат контрольной суммы
}
private static char Convertation(string text) => Bars[Convert.ToInt32(text, 2)]; // Преобразует бинарную строку в число и возвращает соответствующий символ из массива Bars
private static IEnumerable SplitString(this string text, int lenght) // Разбивает строку на подстроки по указанной длине и возвращает их как коллекцию
{
return Enumerable.Range(0, text.Length / lenght)
.Select(i => text.Substring(i * lenght, lenght));
}
///
/// Высота штрихкода (в строках)
///
private const int Height = 4;
///
/// Для получения рамки штрихкода по краям
///
private const string Frame = "0000";
///
/// Допустимые варианты штрихов
///
public static readonly char[] Bars = { '█', '▌', '▐', ' ' };
///
/// Начальный номер паттерна для текстовой строки
///
private const int StartText = 104;
///
/// Начальный номер паттерна для числовой строки
///
private const int StartNumbers = 105;
///
/// Переключить в числовой режим кодирования
///
private const int SwitchToNumbers = 99;
///
/// Переключить в текстовый режим кодирования
///
private const int SwitchToText = 100;
///
/// Номер паттерна завершения
///
private const int Stop = 108;
///
/// Доступные паттерны
///
private static readonly string[] Patterns = {
"11011001100", "11001101100", "11001100110", "10010011000", "10010001100",
"10001001100", "10011001000", "10011000100", "10001100100", "11001001000",
"11001000100", "11000100100", "10110011100", "10011011100", "10011001110",
"10111001100", "10011101100", "10011100110", "11001110010", "11001011100",
"11001001110", "11011100100", "11001110100", "11101101110", "11101001100",
"11100101100", "11100100110", "11101100100", "11100110100", "11100110010",
"11011011000", "11011000110", "11000110110", "10100011000", "10001011000",
"10001000110", "10110001000", "10001101000", "10001100010", "11010001000",
"11000101000", "11000100010", "10110111000", "10110001110", "10001101110",
"10111011000", "10111000110", "10001110110", "11101110110", "11010001110",
"11000101110", "11011101000", "11011100010", "11011101110", "11101011000",
"11101000110", "11100010110", "11101101000", "11101100010", "11100011010",
"11101111010", "11001000010", "11110001010", "10100110000", "10100001100",
"10010110000", "10010000110", "10000101100", "10000100110", "10110010000",
"10110000100", "10011010000", "10011000010", "10000110100", "10000110010",
"11000010010", "11001010000", "11110111010", "11000010100", "10001111010",
"10100111100", "10010111100", "10010011110", "10111100100", "10011110100",
"10011110010", "11110100100", "11110010100", "11110010010", "11011011110",
"11011110110", "11110110110", "10101111000", "10100011110", "10001011110",
"10111101000", "10111100010", "11110101000", "11110100010", "10111011110",
// 100+
"10111101110", "11101011110", "11110101110", "11010000100", "11010010000",
"11010011100", "11000111010", "11010111000", "1100011101011"
};
///
/// Разрешенные символы
///
private static readonly string[] TextSymbols = {
" ","!","\"","#","$","%","&","'","(",")",
"*","+",",","-",".","/","0","1","2","3",
"4","5","6","7","8","9",":",";","<","=",
">","?","@","A","B","C","D","E","F","G",
"H","I","J","K","L","M","N","O","P","Q",
"R","S","T","U","V","W","X","Y","Z","[",
"\\","]","^","_","`","a","b","c","d","e",
"f","g","h","i","j","k","l","m","n","o",
"p","q","r","s","t","u","v","w","x","y",
"z","{","|","|","~"
};
///
/// Разрешенные пары числовых строк
///
private static readonly string[] NumberSymbols = {
"00","01","02","03","04","05","06","07","08","09",
"10","11","12","13","14","15","16","17","18","19",
"20","21","22","23","24","25","26","27","28","29",
"30","31","32","33","34","35","36","37","38","39",
"40","41","42","43","44","45","46","47","48","49",
"50","51","52","53","54","55","56","57","58","59",
"60","61","62","63","64","65","66","67","68","69",
"70","71","72","73","74","75","76","77","78","79",
"80","81","82","83","84","85","86","87","88","89",
"90","91","92","93","94","95","96","97","98","99"
};
#endregion
}