feat: add new tests
This commit is contained in:
@@ -1,8 +1,4 @@
|
||||
/// Support for doing something awesome.
|
||||
///
|
||||
/// More dartdocs go here.
|
||||
library;
|
||||
|
||||
export 'src/potato_pass_core_base.dart';
|
||||
|
||||
// TODO: Export any libraries intended for clients of this package.
|
||||
// Экспортируем наш 6-битный кодировщик
|
||||
export 'src/encoding/compact_text_encoder.dart';
|
||||
79
lib/src/encoding/compact_text_encoder.dart
Normal file
79
lib/src/encoding/compact_text_encoder.dart
Normal file
@@ -0,0 +1,79 @@
|
||||
import 'dart:typed_data';
|
||||
|
||||
/// Класс для упаковки/распаковки текста в 6-битный формат.
|
||||
/// 4 символа упаковываются ровно в 3 байта (сжатие ~62% для кириллицы).
|
||||
abstract class CompactTextEncoder {
|
||||
/// Словарь из 64 символов (индексы от 0 до 63)
|
||||
static const String charset = 'АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯABCDEFGHIJKLMNOPQRSTUVWXYZ -.,_';
|
||||
|
||||
/// Упаковывает строку [text] в байтовый массив Uint8List.
|
||||
static Uint8List encode(String text) {
|
||||
if (text.isEmpty) {
|
||||
return Uint8List(0);
|
||||
}
|
||||
|
||||
final String upperText = text.toUpperCase();
|
||||
final List<int> indices = [];
|
||||
|
||||
// Преобразуем каждый символ в индекс от 0 до 63
|
||||
for (int i = 0; i < upperText.length; i++) {
|
||||
int idx = charset.indexOf(upperText[i]);
|
||||
// Если символа нет в словаре, заменяем на пробел
|
||||
if (idx == -1) {
|
||||
idx = charset.indexOf(' ');
|
||||
}
|
||||
indices.add(idx);
|
||||
}
|
||||
|
||||
// Добиваем длину до кратности 4 символам (символом '_')
|
||||
while (indices.length % 4 != 0) {
|
||||
indices.add(charset.indexOf('_'));
|
||||
}
|
||||
|
||||
final int byteLength = (indices.length ~/ 4) * 3;
|
||||
final Uint8List result = Uint8List(byteLength);
|
||||
|
||||
int byteIdx = 0;
|
||||
for (int i = 0; i < indices.length; i += 4) {
|
||||
int c1 = indices[i];
|
||||
int c2 = indices[i + 1];
|
||||
int c3 = indices[i + 2];
|
||||
int c4 = indices[i + 3];
|
||||
|
||||
// Упаковка 4 x 6 бит (24 бита) в 3 байта по 8 бит
|
||||
result[byteIdx++] = (c1 << 2) | (c2 >> 4);
|
||||
result[byteIdx++] = ((c2 & 0x0F) << 4) | (c3 >> 2);
|
||||
result[byteIdx++] = ((c3 & 0x03) << 6) | c4;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// Распаковывает байтовый массив обратно в строку.
|
||||
static String decode(Uint8List bytes) {
|
||||
if (bytes.isEmpty) {
|
||||
return '';
|
||||
}
|
||||
|
||||
final StringBuffer sb = StringBuffer();
|
||||
|
||||
for (int i = 0; i < bytes.length; i += 3) {
|
||||
int b1 = bytes[i];
|
||||
int b2 = bytes[i + 1];
|
||||
int b3 = bytes[i + 2];
|
||||
|
||||
int c1 = (b1 >> 2) & 0x3F;
|
||||
int c2 = ((b1 & 0x03) << 4) | ((b2 >> 4) & 0x0F);
|
||||
int c3 = ((b2 & 0x0F) << 2) | ((b3 >> 6) & 0x03);
|
||||
int c4 = b3 & 0x3F;
|
||||
|
||||
sb.write(charset[c1]);
|
||||
sb.write(charset[c2]);
|
||||
sb.write(charset[c3]);
|
||||
sb.write(charset[c4]);
|
||||
}
|
||||
|
||||
// Удаляем заполнители и пробелы по краям
|
||||
return sb.toString().replaceAll('_', '').trim();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user