Jelajahi Sumber

SVI Проверка гипотезы

SVI 7 bulan lalu
induk
melakukan
e0dcb06acc

+ 2 - 0
.env

@@ -0,0 +1,2 @@
+PACKER_CMD="pack"
+PACK_FILE="./v_i_m.html"

+ 7 - 1
Makefile

@@ -9,4 +9,10 @@ app.run:
 	cd ./bin && \
 	export PACKER_CMD="pack" && \
 	export PACK_FILE="./v_i_m.html" && \
-	./gpz
+	./gpz
+mod:
+	clear
+	go get -u ./...
+	go mod tidy -compat=1.24.2
+	go mod vendor
+	go fmt ./...

+ 5 - 5
cmd/packer/main.go

@@ -4,17 +4,17 @@ package main
 import (
 	"log"
 
-	"p78git.ddns.net/svi/packer/internal/service"
+	"gitp78su.ipnodns.ru/svi/packer/internal/service"
 )
 
 func main() {
 	log.Printf("main()\n")
-	serv, err := service.NewService()
+	serv, err := service.НовСервис()
 	if err != nil {
-		log.Printf("main(): in create IService, err=\n\t%v\n", err)
+		log.Printf("main(): in create ИСервис, err=\n\t%v\n", err)
 		return
 	}
-	if err := serv.Run(); err != nil {
-		log.Printf("main(): in run IService, err=\n\t%v\n", err)
+	if err := serv.Пуск(); err != nil {
+		log.Printf("main(): in run ИСервис, err=\n\t%v\n", err)
 	}
 }

+ 4 - 2
go.mod

@@ -1,3 +1,5 @@
-module p78git.ddns.net/svi/packer
+module gitp78su.ipnodns.ru/svi/packer
 
-go 1.20
+go 1.26.0
+
+require gitp78su.ipnodns.ru/svi/kern v1.16.0

+ 2 - 0
go.sum

@@ -0,0 +1,2 @@
+gitp78su.ipnodns.ru/svi/kern v1.16.0 h1:xQ+wRV08HSq6O4vYp+8QENTaoBJM538Wlh6PXrG6oDg=
+gitp78su.ipnodns.ru/svi/kern v1.16.0/go.mod h1:amJ5tqZHhWegkUiZu55+z4yctT7JePXRs0mqxqv6FYU=

+ 69 - 0
internal/belt/belt.go

@@ -0,0 +1,69 @@
+// package belt -- лента для исходных данных и результатов
+package belt
+
+import (
+	"log"
+	"os"
+	"sync"
+
+	. "gitp78su.ipnodns.ru/svi/kern/kc/helpers"
+)
+
+type Лента struct {
+	бинИсх      []uint32
+	бинВых      []uint32
+	размерИсход int // Оригинальный размер
+}
+
+var (
+	сам  *Лента
+	блок sync.Mutex
+)
+
+// ЛентаПолуч -- возвращает ленту
+func ЛентаПолуч() *Лента {
+	блок.Lock()
+	defer блок.Unlock()
+	if сам != nil {
+		return сам
+	}
+	сам = &Лента{
+		бинИсх: []uint32{},
+		бинВых: []uint32{},
+	}
+	сам.файлЧитать()
+	return сам
+}
+
+func (сам *Лента) файлЧитать() {
+	файлИмя := os.Getenv("PACK_FILE")
+	Hassert(файлИмя != "", "Пакер.файлЧитать(): env PACK_FILE not set")
+	binData, err := os.ReadFile(файлИмя)
+	Hassert(err == nil, "Пакер.файлЧитать(): in read %q, err=\n\t%v", файлИмя, err)
+	сам.размерИсход = len(binData)
+	for _, val := range binData {
+		сам.бинИсх = append(сам.бинИсх, uint32(val))
+	}
+	сам.бинВых = сам.бинИсх
+	log.Printf("Лента.файлЧитать(): len(%q)=%v\n", файлИмя, len(сам.бинИсх))
+}
+
+// Вых -- выходная лента
+func (сам *Лента) Вых() []uint32 {
+	return сам.бинВых
+}
+
+// Исх -- исходный текст ленты
+func (сам *Лента) Исх() []uint32 {
+	return сам.бинИсх
+}
+
+// ИсхРазмер -- возвращает исходный размер ленты
+func (сам *Лента) ИсхРазмер() int {
+	return len(сам.бинИсх)
+}
+
+// ВыхУст -- устанавливает выходной срез
+func (сам *Лента) ВыхУст(бинВых []uint32) {
+	сам.бинВых = бинВых
+}

+ 65 - 38
internal/packer/dict_keys/dict_keys.go

@@ -5,62 +5,89 @@ import (
 	"fmt"
 	"sync"
 
-	"p78git.ddns.net/svi/packer/pkg/types"
+	. "gitp78su.ipnodns.ru/svi/kern/kc/helpers"
+
+	"gitp78su.ipnodns.ru/svi/packer/pkg/types"
 )
 
-// DictKeys -- словарь ключей для подстановки
-type DictKeys struct {
-	dictKey map[uint16]bool // Словарь ключей подстановки с частотой встреч (для фреквенсера)
-	block   sync.RWMutex
+// СловКлючи -- словарь ключей для подстановки
+type СловКлючи struct {
+	sync.RWMutex
+	слов map[uint32]bool // Словарь ключей подстановки с частотой встреч (для частотника)
 }
 
-// NewDictKeys -- возвращает новый словарь для подстановки ключей
-func NewDictKeys() *DictKeys {
-	sf := &DictKeys{
-		dictKey: map[uint16]bool{},
+var (
+	сам  *СловКлючи
+	блок sync.Mutex
+)
+
+// СловКлючиПолуч -- возвращает новый словарь для подстановки ключей
+func СловКлючиПолуч() *СловКлючи {
+	блок.Lock()
+	defer блок.Unlock()
+	if сам != nil {
+		return сам
 	}
-	_ = types.IDictKeys(sf)
-	return sf
+	сам = &СловКлючи{
+		слов: map[uint32]bool{},
+	}
+	_ = types.ИСловКлючи(сам)
+	return сам
 }
 
-// Keys -- возвращает словарь ключей
-func (sf *DictKeys) Keys() []uint16 {
-	sf.block.RLock()
-	defer sf.block.RUnlock()
-	lstKey := []uint16{}
-	for key := range sf.dictKey {
+// Ключи -- возвращает словарь ключей
+func (сам *СловКлючи) Ключи() []uint32 {
+	сам.RLock()
+	defer сам.RUnlock()
+	lstKey := make([]uint32, 0, len(сам.слов))
+	for key := range сам.слов {
 		lstKey = append(lstKey, key)
 	}
-
 	return lstKey
 }
 
-// Add -- добавляет ключ в словарь
-func (sf *DictKeys) Add(key uint16) {
-	sf.block.Lock()
-	defer sf.block.Unlock()
-	sf.dictKey[key] = true
+// ПервичЗаполн -- заполняет первичные ключи
+func (сам *СловКлючи) ПервичЗаполн(бинТекст []uint32) {
+	словПервич := map[int]bool{}
+	for инд := range 256 {
+		словПервич[инд] = true
+	}
+	for _, знач := range бинТекст {
+		delete(словПервич, int(знач))
+	}
+	for ключ := range словПервич {
+		сам.слов[uint32(ключ)] = true
+	}
+}
+
+// Доб -- добавляет ключ в словарь
+func (сам *СловКлючи) Доб(ключ uint32) {
+	сам.Lock()
+	defer сам.Unlock()
+	_, еслиЕсть := сам.слов[ключ]
+	Hassert(!еслиЕсть, "СловКлючи.Доб(): ключ(%v) уже есть", ключ)
+	сам.слов[ключ] = true
 }
 
-// Stat -- отдаёт статистику словаря
-func (sf *DictKeys) Stat() string {
-	sf.block.RLock()
-	defer sf.block.RUnlock()
-	res := fmt.Sprintf("DictKeys{len:%v}", len(sf.dictKey))
+// Стата -- отдаёт статистику словаря
+func (сам *СловКлючи) Стата() string {
+	сам.RLock()
+	defer сам.RUnlock()
+	res := fmt.Sprintf("СловКлючи.Стата(): всего=%v", len(сам.слов))
 	return res
 }
 
-// IsExists -- проверяет существует ли такой ключ
-func (sf *DictKeys) IsExists(key uint16) bool {
-	sf.block.RLock()
-	defer sf.block.RUnlock()
-	_, isOk := sf.dictKey[key]
+// ЕслиЕсть -- проверяет существует ли такой ключ
+func (сам *СловКлючи) ЕслиЕсть(key uint32) bool {
+	сам.RLock()
+	defer сам.RUnlock()
+	_, isOk := сам.слов[key]
 	return isOk
 }
 
-// Len -- возвращает размер словаря ключей
-func (sf *DictKeys) Len() int {
-	sf.block.RLock()
-	defer sf.block.RUnlock()
-	return len(sf.dictKey)
+// Всего -- возвращает размер словаря ключей
+func (сам *СловКлючи) Всего() int {
+	сам.RLock()
+	defer сам.RUnlock()
+	return len(сам.слов)
 }

+ 23 - 23
internal/packer/freq_pair/freq_pair.go

@@ -1,45 +1,45 @@
-// package freq_pair -- наиблоее частотная пара
+// package freq_pair -- наиболее частотная пара
 package freq_pair
 
 import (
 	"fmt"
 )
 
-// FreqPair -- самая частотная пара
-type FreqPair struct {
+// ЧастПара -- самая частотная пара
+type ЧастотПара struct {
 	Val1_, Val2_ int    // Самые частотные значения
-	Key0_, Key1_ uint16 // Самый частотные ключи
+	Key0_, Key1_ uint32 // Самый частотные ключи
 	Combo_       string // Самая выгодная комбинация для сжатия(11, 12, 21, 22)
 }
 
-// SetVal2 -- устанавливает значения частотных пар
-func (sf *FreqPair) SetVal1(key uint16, val int) {
-	if val > sf.Val2_ {
-		sf.Val1_ = sf.Val2_
-		sf.Key0_ = sf.Key1_
+// SetVal1 -- устанавливает значения частотных пар
+func (сам *ЧастотПара) SetVal1(key uint32, val int) {
+	if val > сам.Val2_ {
+		сам.Val1_ = сам.Val2_
+		сам.Key0_ = сам.Key1_
 
-		sf.Val2_ = val
-		sf.Key1_ = key
+		сам.Val2_ = val
+		сам.Key1_ = key
 		return
 	}
-	sf.Val1_ = val
-	sf.Key0_ = key
+	сам.Val1_ = val
+	сам.Key0_ = key
 }
 
-// String -- строковое представление частотной пары
-func (sf *FreqPair) String() string {
+// String -- строковое представление частотных пар
+func (сам *ЧастотПара) String() string {
 	str := fmt.Sprintf("{key1:%v val1:%v; key2:%v val2:%v; combo:%q}",
-		sf.Key0_,
-		sf.Val1_,
-		sf.Key1_,
-		sf.Val2_,
-		sf.Combo_,
+		сам.Key0_,
+		сам.Val1_,
+		сам.Key1_,
+		сам.Val2_,
+		сам.Combo_,
 	)
 	return str
 }
 
 // SetKeys -- устанавливает ключи замен
-func (sf *FreqPair) SetKeys(key0, key1 uint16) {
-	sf.Key0_ = key0
-	sf.Key1_ = key1
+func (сам *ЧастотПара) SetKeys(key0, key1 uint32) {
+	сам.Key0_ = key0
+	сам.Key1_ = key1
 }

+ 80 - 77
internal/packer/frequencer/frequencer.go

@@ -1,4 +1,4 @@
-// package frequencer -- ищет минимально частотную пару
+// package Частотник -- ищет минимально частотную пару
 package frequencer
 
 import (
@@ -6,118 +6,121 @@ import (
 	"log"
 	"time"
 
-	"p78git.ddns.net/svi/packer/pkg/types"
+	// . "gitp78su.ipnodns.ru/svi/kern/kc/helpers"
+
+	"gitp78su.ipnodns.ru/svi/packer/internal/belt"
+	"gitp78su.ipnodns.ru/svi/packer/internal/packer/dict_keys"
+	"gitp78su.ipnodns.ru/svi/packer/pkg/types"
 )
 
-// Frequencer -- ищет минимально частотную пару
-type Frequencer struct {
-	serv       types.IService
-	packer     types.IPacker
-	key0, key1 uint16          // Частотные кючи
-	oldKeys    map[uint32]bool // Перебранные комбинации для key0
+// Частотник -- ищет минимально частотную пару
+type Частотник struct {
+	лента                *belt.Лента
+	словКлючи            *dict_keys.СловКлючи
+	ключСтарш, ключМладш uint32          // Частотные ключи
+	ключиСтарые          map[uint32]bool // Перебранные комбинации для key0
 }
 
-// NewFrequencer -- возвращает новый минимальный искатель
-func NewFrequencer(packer types.IPacker) (*Frequencer, error) {
-	if packer == nil {
-		return nil, fmt.Errorf("NewFrequencer(): IPacker==nil")
-	}
-	sf := &Frequencer{
-		serv:    packer.Serv(),
-		packer:  packer,
-		oldKeys: map[uint32]bool{},
+// НовЧастотник -- возвращает новый минимальный искатель
+func НовЧастотник() *Частотник {
+	сам := &Частотник{
+		ключиСтарые: map[uint32]bool{},
+		словКлючи:   dict_keys.СловКлючиПолуч(),
+		лента:       belt.ЛентаПолуч(),
 	}
-	return sf, nil
+	_ = types.ИЧастотник(сам)
+	return сам
 }
 
-// Run -- запускает вычисление частотной пары
+func (сам *Частотник) еслиПараЕсть(ключСтарш, ключМладш uint32) bool {
+	число := ключСтарш*65536 + ключМладш
+	_, isOk := сам.ключиСтарые[число]
+	return isOk
+}
+
+// Пуск -- запускает вычисление частотной пары
 //
 //	Считается успехом, если нашёл 5 замен словарных ключей
-func (sf *Frequencer) Run() error {
-	lstKeys := sf.serv.Packer().DictKeys().Keys()
-	if len(lstKeys) <= 1 {
-		return fmt.Errorf("Frequencer.Run(): lstKeys is empty")
-	}
-	key0 := uint16(0)
-	key1 := uint16(0)
-	binData := sf.serv.Packer().BinData()
-	num := uint32(0)
-	fnCheckPair := func() bool {
-		num = uint32(key0)*65536 + uint32(key1)
-		_, isOk := sf.oldKeys[num]
-		return isOk
+func (сам *Частотник) Пуск() error {
+	списКлючи := сам.словКлючи.Ключи()
+	if len(списКлючи) <= 1 {
+		return fmt.Errorf("Частотник.Пуск(): lstKeys is empty")
 	}
-	fnAddKey := func() {
-		num = uint32(key0)*65536 + uint32(key1)
-		sf.oldKeys[num] = true
+	ключСтарш := uint32(0)
+	ключМладш := uint32(0)
+	binData := сам.лента.Вых()
+	число := uint32(0)
+	фнКлючДоб := func() {
+		число = uint32(ключСтарш)*65536 + uint32(ключМладш)
+		сам.ключиСтарые[число] = true
 	}
-	count := 0
-	val0 := uint16(0)
-	fnCompare := func(ind int) {
-		val1 := binData[ind]
-		if val0 != key0 {
+	счёт := 0
+	значСтарш := uint32(0)
+	фнСравнить := func(инд int) {
+		значМладш := binData[инд]
+		if значСтарш != ключСтарш {
 			return
 		}
-		if val1 != key1 {
+		if значМладш != ключМладш {
 			return
 		}
-		count++
-		if ind >= len(binData) {
+		счёт++
+		if инд >= len(binData) {
 			return
 		}
-		val0 = binData[ind]
+		значСтарш = binData[инд]
 	}
-	fnKey1 := func() bool { // Ищет совпадение для key0 и key1
-		timeBeg := time.Now().UnixMilli() // Для ограничения времени поиска бесполезной комбинации
-		for _, key1 = range lstKeys {
-			if fnCheckPair() {
+	фнКлюч1 := func() bool { // Ищет совпадение для ключСтарш и ключМладш
+		времНач := time.Now().UnixMilli() // Для ограничения времени поиска бесполезной комбинации
+		for _, ключМладш = range списКлючи {
+			if сам.еслиПараЕсть(ключСтарш, ключМладш) {
 				continue
 			}
-			count = 0
-			val0 = binData[0]
-			countCall := 0
-			for ind := 1; ind < len(binData); ind++ {
-				val1 := binData[ind]
-				fnCompare(ind)
-				countCall++
-				if countCall > 5000 {
-					timeDelta := time.Now().UnixMilli() - timeBeg
+			счёт = 0
+			значСтарш = binData[0]
+			счётВызов := 0
+			for инд_ := 1; инд_ < len(binData); инд_++ {
+				значМладш := binData[инд_]
+				фнСравнить(инд_)
+				счётВызов++
+				if счётВызов > 5000 {
+					timeDelta := time.Now().UnixMilli() - времНач
 					if timeDelta > 100 {
-						fnAddKey()
+						фнКлючДоб()
 						return false
 					}
-					countCall = 0
+					счётВызов = 0
 				}
 
-				if count >= 10 {
-					fnAddKey()
-					timeDelta := time.Now().UnixMilli() - timeBeg
-					log.Printf("Frequencer.fnKey1(): timeDelta=%vmsec\n", timeDelta)
+				if счёт >= 10 {
+					фнКлючДоб()
+					времДельта := time.Now().UnixMilli() - времНач
+					log.Printf("Частотник.fnKey1(): timeDelta=%v msec\n", времДельта)
 					return true
 				}
-				val0 = val1
+				значСтарш = значМладш
 			}
-			fnAddKey()
+			фнКлючДоб()
 		}
 		return false
 	}
-	isFind := false
-	for _, key0 = range lstKeys {
-		if fnKey1() {
-			isFind = true
+	еслиНайдено := false
+	for _, ключСтарш = range списКлючи {
+		if фнКлюч1() {
+			еслиНайдено = true
 			break
 		}
 	}
-	if !isFind {
-		return fmt.Errorf("Frequencer.Run(): not find keys for change, checked=%v", len(sf.oldKeys))
+	if !еслиНайдено {
+		return fmt.Errorf("Частотник.Пуск(): not find keys for change, checked=%v", len(сам.ключиСтарые))
 	}
-	sf.key0 = key0
-	sf.key1 = key1
-	log.Printf("Frequencer.Run(): keys=[%v %v], checked=%v\n", sf.key0, sf.key1, len(sf.oldKeys))
+	сам.ключСтарш = ключСтарш
+	сам.ключМладш = ключМладш
+	log.Printf("Частотник.Пуск(): ключи=[%v %v], checked=%v\n", сам.ключСтарш, сам.ключМладш, len(сам.ключиСтарые))
 	return nil
 }
 
-// Keys -- возвращает найденные ключи
-func (sf *Frequencer) Keys() (uint16, uint16) {
-	return sf.key0, sf.key1
+// Ключи -- возвращает найденные ключи
+func (сам *Частотник) Ключи() (uint32, uint32) {
+	return сам.ключСтарш, сам.ключМладш
 }

+ 108 - 142
internal/packer/packer.go

@@ -5,204 +5,170 @@ import (
 	"fmt"
 	"log"
 	"math"
-	"os"
 	"time"
 
-	"p78git.ddns.net/svi/packer/internal/packer/dict_keys"
-	"p78git.ddns.net/svi/packer/internal/packer/freq_pair"
-	"p78git.ddns.net/svi/packer/internal/packer/frequencer"
-	"p78git.ddns.net/svi/packer/pkg/types"
+	. "gitp78su.ipnodns.ru/svi/kern/kc/helpers"
+
+	"gitp78su.ipnodns.ru/svi/packer/internal/belt"
+	"gitp78su.ipnodns.ru/svi/packer/internal/packer/dict_keys"
+	"gitp78su.ipnodns.ru/svi/packer/internal/packer/freq_pair"
+	"gitp78su.ipnodns.ru/svi/packer/internal/packer/frequencer"
+	"gitp78su.ipnodns.ru/svi/packer/pkg/types"
 )
 
-// Packer -- упаковщик сервиса
-type Packer struct {
-	serv        types.IService
-	dictKeys    types.IDictKeys     // Словарь ключей
-	freqPair    *freq_pair.FreqPair // Частотная пара
-	frequencer  types.IFrequencer   // Подбор частотной пары
-	binData     []uint16            // То, что останется после замен
-	timeTotal   float32             // Общее время в сек
-	totalChange int                 // Общее число замен
-	originSize  int                 // Оригинальный размер
-	binNew      []uint16            // Буфер новых данных
+// Пакер -- упаковщик сервиса
+type Пакер struct {
+	словКлючи  *dict_keys.СловКлючи  // Словарь ключей
+	частотПара *freq_pair.ЧастотПара // Частотная пара
+	частотник  types.ИЧастотник      // Подбор частотной пары
+	времВсего  float32               // Общее время в сек
+	заменВсего int                   // Общее число замен
+	лента      *belt.Лента
 }
 
-// NewPacker -- возвращает ноый пакер
-func NewPacker(serv types.IService) (*Packer, error) {
-	if serv == nil {
-		return nil, fmt.Errorf("NewPacker(): IService==nil")
-	}
-	sf := &Packer{
-		serv:     serv,
-		dictKeys: dict_keys.NewDictKeys(),
-		freqPair: &freq_pair.FreqPair{},
-		binData:  []uint16{},
-		binNew:   []uint16{0, 0, 0},
-	}
-	var err error
-	sf.frequencer, err = frequencer.NewFrequencer(sf)
-	if err != nil {
-		return nil, fmt.Errorf("NewPacker(): in create IFrequencer, err=\n\t%w", err)
+// НовПакер -- возвращает новый пакер
+func НовПакер() *Пакер {
+	сам := &Пакер{
+		словКлючи:  dict_keys.СловКлючиПолуч(),
+		частотПара: &freq_pair.ЧастотПара{},
+		лента:      belt.ЛентаПолуч(),
+		частотник:  frequencer.НовЧастотник(),
 	}
-	_ = types.IPacker(sf)
-	return sf, nil
+	return сам
 }
 
-// Run -- запускает упаковку
-func (sf *Packer) Run() error {
-	log.Printf("Packer.Run()\n")
-	{ // Чтение файла
-		fileName := os.Getenv("PACK_FILE")
-		if fileName == "" {
-			return fmt.Errorf("Packer.Run(): env PACK_FILE not set")
-		}
-		binData, err := os.ReadFile(fileName)
-		if err != nil {
-			return fmt.Errorf("Packer.Run(): in read %q, err=\n\t%w", fileName, err)
-		}
-		sf.originSize = len(binData)
-		for _, val := range binData {
-			sf.binData = append(sf.binData, uint16(val))
-		}
-		log.Printf("Packer.Run(): len(%q)=%v\n", fileName, len(sf.binData))
-	}
-	round := 1
+// Пуск -- запускает упаковку
+func (сам *Пакер) Пуск() error {
+	log.Printf("Пакер.Пуск()\n")
+	сам.словКлючи.ПервичЗаполн(сам.лента.Исх())
+	раундСчёт := 1
 	for { // Главный цикл сжатия
-		log.Printf("Packer.Run(): round=%v, lenDict=%v\n", round, sf.dictKeys.Len())
-		if !sf.round() {
+		if !сам.раунд() {
 			break
 		}
-		round++
+		log.Printf("Пакер.Пуск(): раунд=%v, ключиВсего=%v\n\n", раундСчёт, сам.словКлючи.Всего())
+		раундСчёт++
 	}
 	return nil
 }
 
-// Serv -- возвращает сервис
-func (sf *Packer) Serv() types.IService {
-	return sf.serv
+// СловКлючи -- возвращает словарь ключей для подстановки
+func (sf *Пакер) СловКлючи() types.ИСловКлючи {
+	return sf.словКлючи
 }
 
-// BinData -- возвращает бинарны данные для упаковки
-func (sf *Packer) BinData() []uint16 {
-	return sf.binData
-}
-
-// DictKeys -- возвращает словарь ключей для подстановки
-func (sf *Packer) DictKeys() types.IDictKeys {
-	return sf.dictKeys
+func (сам *Пакер) времРаунд(времНач int64) {
+	времКонец := time.Now().Local().UnixMilli()
+	времРаунд := float32(времКонец-времНач) / 1000
+	сам.времВсего += времРаунд
+	словБит := 8
+	ключейВсего := сам.словКлючи.Всего()
+	switch {
+	case 256 <= ключейВсего && ключейВсего < 512:
+		словБит = 9
+	case 512 <= ключейВсего && ключейВсего < 1024:
+		словБит = 10
+	case 1024 <= ключейВсего && ключейВсего < 2048:
+		словБит = 11
+	case 2048 <= ключейВсего && ключейВсего < 4096:
+		словБит = 12
+	case 4096 <= ключейВсего && ключейВсего < 8191:
+		словБит = 13
+	case 8192 <= ключейВсего && ключейВсего < 16383:
+		словБит = 14
+	case ключейВсего >= 16384:
+		Hassert(false, "Пакер.времРаунд(): слишком много ключей(%v)", ключейВсего)
+	}
+	размерНов := int((float32(len(сам.лента.Вых()) + ключейВсего)) * (float32(словБит) / 8))
+	сжатие := float32(размерНов) / float32(сам.лента.ИсхРазмер()) * 100
+	log.Printf("Пакер.времРаунд(): время(всего=%0.2fsec, раунд=%0.2fsec), сжатие=%0.2f%%, заменВсего=%v\n",
+		сам.времВсего,
+		времРаунд,
+		сжатие,
+		сам.заменВсего)
+	log.Printf("Пакер.времРаунд(): размерИсх=%v размерНов=%v\n", сам.лента.ИсхРазмер(), размерНов)
 }
 
 // Выполняет раунд сжатия
-func (sf *Packer) round() bool {
-	timeBeg := time.Now().Local().UnixMilli()
-	defer func() {
-		timeEnd := time.Now().Local().UnixMilli()
-		timeDelta := float32(timeEnd-timeBeg) / 1000
-		sf.timeTotal += timeDelta
-		binOrigin := sf.originSize * 8
-		multFactor := 8
-		lenDict := sf.dictKeys.Len()
-		switch {
-		case lenDict < 256:
-			multFactor = 8
-		case 256 <= lenDict && lenDict < 512:
-			multFactor = 9
-		case 512 <= lenDict && lenDict < 1024:
-			multFactor = 10
-		case 1024 <= lenDict && lenDict < 2048:
-			multFactor = 11
-		case 2048 <= lenDict && lenDict < 4096:
-			multFactor = 12
-		case 4096 <= lenDict && lenDict < 8200:
-			multFactor = 13
-		default:
-			multFactor = 14
-		}
-		binPack := len(sf.binData)*multFactor + lenDict*3*multFactor
-		ratio := (1 - float32(binOrigin)/float32(binPack)) * 100
-		log.Printf("Packer.Round(): timeTotal=%0.2fsec, timeRound=%0.2fsec, ration=%0.2f%%, totalChange=%v\n\n",
-			sf.timeTotal,
-			timeDelta,
-			ratio,
-			sf.totalChange)
-	}()
-	sf.dictUp()
-	if err := sf.frequencer.Run(); err != nil {
-		log.Printf("Packer.round(): in work IFrequencer, err=\n\t%v\n", err)
+func (сам *Пакер) раунд() bool {
+	времНач := time.Now().Local().UnixMilli()
+	defer сам.времРаунд(времНач)
+	// сам.словУст()
+	if err := сам.частотник.Пуск(); err != nil {
+		log.Printf("Пакер.round(): in work IFrequencer, err=\n\t%v\n", err)
 		return false
 	}
-	sf.freqPair.SetKeys(sf.frequencer.Keys())
-	keyNext, err := sf.keyNext()
+	сам.частотПара.SetKeys(сам.частотник.Ключи())
+	keyNext, err := сам.keyNext()
 	if err != nil {
-		log.Printf("Packer.round(): limit keys, err=\n\t%v\n", err)
+		log.Printf("Пакер.раунд(): limit keys, err=\n\t%v\n", err)
 		return false
 	}
-	sf.changeKey(keyNext)
+	сам.сменитьКлюч(keyNext)
 	return true
 }
 
 // Заменяет частотную пару на указанный ключ
-func (sf *Packer) changeKey(key uint16) {
-	sf.binNew = sf.binNew[:0]
-	val0 := sf.binData[0]
+func (сам *Пакер) сменитьКлюч(key uint32) {
+	binNew := сам.лента.Вых()
+	исхРазмер := len(binNew)
+	binNew = binNew[:0]
+	val0 := binNew[0]
 	ind := 1
-	val1 := sf.binData[ind]
+	val1 := binNew[ind]
 	fnNext := func() bool { // вычисляет сдвиг после замены
-		sf.binNew = append(sf.binNew, key)
-		if ind+1 >= len(sf.binData) { // Достигнут предел прохода
+		binNew = append(binNew, key)
+		if ind+1 >= len(binNew) { // Достигнут предел прохода
 			return false
 		}
 		ind++
-		val0 = sf.binData[ind]
-		if ind+1 >= len(sf.binData) { // Достигнут предел прохода
+		val0 = binNew[ind]
+		if ind+1 >= len(binNew) { // Достигнут предел прохода
 			return false
 		}
 		ind++
-		val1 = sf.binData[ind]
+		val1 = binNew[ind]
 		return true
 	}
-	key0 := sf.freqPair.Key0_
-	key1 := sf.freqPair.Key1_
-	for ind < len(sf.binData) {
-		val1 = sf.binData[ind]
+	key0 := сам.частотПара.Key0_
+	key1 := сам.частотПара.Key1_
+	for ind < len(binNew) {
+		val1 = binNew[ind]
 		if val0 == key0 && val1 == key1 {
 			fnNext()
 			continue
 		}
-		sf.binNew = append(sf.binNew, val0)
+		binNew = append(binNew, val0)
 		val0 = val1
 		ind++
 	}
-	countChange := len(sf.binData) - len(sf.binNew)
-	sf.totalChange += countChange
-	log.Printf("Packer.changeKey(): len{old=%v, new=%v}, numChange=%v\n",
-		len(sf.binData),
-		len(sf.binNew),
-		countChange)
-	sf.binData = sf.binNew
+	countChange := исхРазмер - len(binNew)
+	сам.заменВсего += countChange
+	log.Printf("Пакер.сменитьКлюч(): раундЗамены=%v\n", countChange)
+	сам.лента.ВыхУст(binNew)
 }
 
-// Ищёт следующий свободный ключ
-func (sf *Packer) keyNext() (uint16, error) {
-	key := uint16(0)
+// Ищет следующий свободный ключ
+func (sf *Пакер) keyNext() (uint32, error) {
+	key := uint32(0)
 	for {
-		if !sf.dictKeys.IsExists(key) {
+		if !sf.словКлючи.ЕслиЕсть(key) {
 			return key, nil
 		}
 		key++
 		if key == math.MaxUint16 {
-			return 0, fmt.Errorf("Packer.keyNext(): key up to limit uint32")
+			return 0, fmt.Errorf("Пакер.keyNext(): key up to limit uint32")
 		}
 	}
 }
 
 // Собирает словарь ключей из текста
-func (sf *Packer) dictUp() {
-	// Собрать встречающиеся ключи
-	for _, val := range sf.binData {
-		if !sf.dictKeys.IsExists(val) {
-			sf.dictKeys.Add(val)
-			continue
-		}
-	}
-}
+// func (sf *Пакер) словУст() {
+// 	// Собрать встречающиеся ключи
+// 	for _, знач := range sf.бинТекст {
+// 		if !sf.словКлючи.ЕслиЕсть(знач) {
+// 			sf.словКлючи.Доб(знач)
+// 			continue
+// 		}
+// 	}
+// }

+ 18 - 29
internal/service/service.go

@@ -1,4 +1,4 @@
-// package service -- главный тип пакера
+// package Сервис -- главный тип пакера
 package service
 
 import (
@@ -6,48 +6,37 @@ import (
 	"log"
 	"os"
 
-	"p78git.ddns.net/svi/packer/internal/packer"
-	"p78git.ddns.net/svi/packer/pkg/types"
+	"gitp78su.ipnodns.ru/svi/packer/internal/packer"
 )
 
-// Service -- главный тип пакера
-type Service struct {
-	packer types.IPacker
+// Сервис -- главный тип пакера
+type Сервис struct {
+	пакер *packer.Пакер
 }
 
-// NewService -- возвращает новый сервис
-func NewService() (*Service, error) {
-	log.Printf("NewService()\n")
-	sf := &Service{}
-	var err error
-	sf.packer, err = packer.NewPacker(sf)
-	if err != nil {
-		return nil, fmt.Errorf("NewService(): in create Packer, err=\n\t%w", err)
-	}
-	_ = types.IService(sf)
-	return sf, nil
+// НовСервис -- возвращает новый сервис
+func НовСервис() (*Сервис, error) {
+	log.Printf("НовСервис()\n")
+	сам := &Сервис{}
+	сам.пакер = packer.НовПакер()
+	return сам, nil
 }
 
-// Run -- запускает сервис в работу
-func (sf *Service) Run() error {
-	log.Printf("Service.Run()\n")
+// Пуск -- запускает сервис в работу
+func (sf *Сервис) Пуск() error {
+	log.Printf("Сервис.Пуск()\n")
 	cmd := os.Getenv("PACKER_CMD")
 	if cmd == "" {
-		return fmt.Errorf("Service.Run(): env PACKER_CMD not set")
+		return fmt.Errorf("Сервис.Пуск(): env PACKER_CMD not set")
 	}
 	switch cmd {
 	case "pack":
-		err := sf.packer.Run()
+		err := sf.пакер.Пуск()
 		if err != nil {
-			return fmt.Errorf("Service.Run(): in run IPacker, err=\n\t%w", err)
+			return fmt.Errorf("Сервис.Пуск(): in Пуск IPacker, err=\n\t%w", err)
 		}
 	default:
-		return fmt.Errorf("Service.Run(): unknown env PACKER_CMD(%q)", cmd)
+		return fmt.Errorf("Сервис.Пуск(): unknown env PACKER_CMD(%q)", cmd)
 	}
 	return nil
 }
-
-// Packer -- возвращает упаковщик
-func (sf *Service) Packer() types.IPacker {
-	return sf.packer
-}

+ 12 - 12
pkg/types/idict_keys.go

@@ -1,15 +1,15 @@
 package types
 
-// IDictKeys -- словарь ключей
-type IDictKeys interface {
-	// Len -- возвращает число ключей в словаре
-	Len() int
-	// IsExists -- проверяет существует ли такой ключ
-	IsExists(uint16) bool
-	// Stat -- вываливает статистику
-	Stat() string
-	// Add -- добавляет ключ в словарь
-	Add(uint16)
-	// Keys -- возвращает словарь ключей
-	Keys() []uint16
+// ИСловКлючи -- словарь ключей
+type ИСловКлючи interface {
+	// Всего -- возвращает число ключей в словаре
+	Всего() int
+	// ЕслиЕсть -- проверяет существует ли такой ключ
+	ЕслиЕсть(uint32) bool
+	// Стата -- вываливает статистику
+	Стата() string
+	// Доб -- добавляет ключ в словарь
+	Доб(uint32)
+	// Ключи -- возвращает список ключей
+	Ключи() []uint32
 }

+ 6 - 6
pkg/types/ifrequencer.go

@@ -1,9 +1,9 @@
 package types
 
-// IFrequencer -- анализатор частот
-type IFrequencer interface {
-	// Run -- запускает частотник в работу
-	Run() error
-	// Keys -- возвращает подобранные ключи
-	Keys() (key0, key1 uint16)
+// ИЧастотник -- анализатор частот
+type ИЧастотник interface {
+	// Пуск -- запускает частотник в работу
+	Пуск() error
+	// Ключи -- возвращает подобранные ключи
+	Ключи() (key0, key1 uint32)
 }

+ 8 - 10
pkg/types/ipacker.go

@@ -1,13 +1,11 @@
 package types
 
-// IPacker -- упаковщик
-type IPacker interface {
-	// DictKeys -- возвращает словарь ключей
-	DictKeys() IDictKeys
-	// BinData -- возвращает бинарные данные упаковки
-	BinData() []uint16
-	// Serv -- возвращает сервис
-	Serv() IService
-	// Run -- запуск пакера
-	Run() error
+// ИПакер -- упаковщик
+type ИПакер interface {
+	// СловКлючи -- возвращает словарь ключей
+	СловКлючи() ИСловКлючи
+	// Результат -- возвращает бинарные данные упаковки
+	Результат() []uint32
+	// Пуск -- запуск пакера
+	Пуск() error
 }

+ 0 - 8
pkg/types/iservice.go

@@ -1,8 +0,0 @@
-// package types -- интерфейсы для проекта
-package types
-
-// IService -- сервис
-type IService interface {
-	// Packer - -возвращает упаковщик
-	Packer() IPacker
-}

+ 116 - 0
vendor/gitp78su.ipnodns.ru/svi/kern/LICENSE.md

@@ -0,0 +1,116 @@
+# Универсальная коммунистическая лицензия
+
+`Версия 1.0.6` `2025-03-10 09:24:36 MSK +03`
+
+Сокращённое название:
+
+- русский: УКЛ;
+- английский: UCL.
+
+## Определения
+
+**Трудящийся**: человек, для которого приоритетным способом обеспечения своей жизни является реализация своего производительного труда каким-либо образом.
+
+**Капиталист**: человек, который является владельцем материальных и трудовых ресурсов, инструментов производства и присваивает в личное владение хотя бы часть прибавочной стоимости в ходе товарного производства.
+
+**Объект лицензирования**: любой результат труда, в отношение которого устанавливаются правовые отношения настоящей лицензией (далее `ОЛ`); `ОЛ` не может быть ничего, кроме артефакта, который потребовал для своего создания производительного труда.
+
+**Автор ОЛ**: человек (или несколько человек), который является автором `ОЛ` и всех сопутствующих материалов, которые он создал непосредственно.
+
+**Потребитель ОЛ**: `трудящийся` или `капиталист`, который использует настоящий `ОЛ`, с соблюдением требований данной лицензии или с нарушением требований данной лицензии.
+
+**Производный объект лицензирования**: `ОЛ` со всеми сопутствующими материалами, в котором доля модификации не превышает 50%; производный `ОЛ` подпадает под действие этих же лицензионных требований в полном объёме.
+
+**Лицензионные требования**: требования на условия использование `ОЛ`, которые предъявляет автор `ОЛ` при его использовании потребителем `ОЛ`. `Лицензионные требования` автоматически вступают в силу, если потребитель ОЛ использует объект лицензирования в любым способом.
+
+```mermaid
+flowchart TD
+  subgraph Потребитель
+    Трудящийся
+    Капиталист
+  end
+  subgraph Права
+    subgraph отчуждаемые
+      ПК[копирование]
+      ПМ[модификация]
+      ПИ[использование]
+    end
+    subgraph неотчуждаемые
+      ПА[авторское]
+      ПВ[владение]
+    end
+    ПК --> ОП[Отчуждаемые права]
+    ПМ --> ОП
+    ПИ --> ОП
+    ПА --> НП[Неотчуждаемые права]
+    ПВ --> НП
+  end
+  ОЛ[Объект лицензирования] --> Права
+  ОП --> Трудящийся
+  ОП --> Автор
+  ОП -.-x Капиталист
+  Автор --> Капиталист
+  НП --> Автор
+```
+
+## Права
+
+**Неотчуждаемое право**: такой вид права, который при любых условиях и/или обстоятельствах не может быть утрачен.
+
+**Авторское право**: неотчуждаемое право автора (или группы авторов) на своё произведение ни при каких условиях; авторское право означает, что автором `ОЛ` является конкретный человек (или группа людей) и ничего более.
+
+**Право владения**: особое, неотчуждаемое право в условиях капитализма, по непосредственному владению `ОЛ` `автором`; возможно отчуждаемое право в условиях социализма на свободном решении отказа  `автора` от права владения `ОЛ` в общественное пользование `трудящимися`.
+
+**Отчуждаемое право**: такой вид права, который может быть передан или отозван по различным основаниям.
+
+**Свободное решение**: решение двух сторон по обладанию отчуждаемыми правами без какого-либо внешнего давления, которое не принуждает любую из сторон  (с явной потерей своей пользы в явную пользу другой стороны или наоборот) передавать или принимать права любой из сторон.
+
+**Право копирования**:  возможное отчуждаемое право, по  `свободному решению`` сторон; копирование -- создание копии ПО. подлежащее данным лицензионным требованиям.
+
+**Право модификации**: возможное отчуждаемое право, по `свободному решению`` сторон; модификация -- доработка, декомпиляция. патчинг и другие виды изменений в отношении ПО, которое подлежит данному лицензированию.
+
+**Право использования**: возможное отчуждаемое право, по свободному решению сторон; использование -- использование `ОЛ` по функциональному назначению _и все действия_, связанные с технологией использования такого `ОЛ`, подлежащему данным лицензионным требованиям; право использования для `капиталиста` -- -- особое индивидуальное разрешение `капиталисту` на использование конкретного `ЛО` или его частью, которое подлежит данным лицензионным требованиям.
+
+## Обязанности сторон
+
+`Автор` в рамках определений в настоящих лицензионных требований _разрешает_ всем `трудящимся` мира использовать права на настоящий `ОЛ`:
+
+- копирования;
+- использования;
+- модификации.
+
+`Автор` в рамках определений настоящих лицензионных требований _запрещает_ всем `капиталистам` мира право копирования, использования, модификации настоящего `ОЛ` и любые права не указанные здесь, если это не оговорено особо или передача прав не является свободной.
+
+`Автор` _явно_ запрещает использование `ОЛ`, в случае его применения любым способом против `трудящихся`.
+
+`Автор` не даёт _никаких_ гарантий в отношении настоящего `ОЛ`:
+
+- необходимого функционала;
+- необходимой архитектуры;
+- необходимых архитектурных свойств;
+- необходимого качества и/или кодирования, материалов;
+- необходимого количества тестирования;
+- необходимых возможностей масштабирования;
+- отсутствия возможного ущерба;
+- возможной упущенной выгоды;
+- иных возможных потерь, которые не упомянуты здесь.
+
+`Автор` может дать дополнительные гарантии по своему усмотрению или договорённости с `потребителем`; подобные договорённости оформляются отдельным приложением и оно имеет приоритет надо отказом от гарантий, перечисленными (или не упомянутыми) выше.
+
+`Автор` гарантирует, что не включает в свой код деструктивный функционал, но оставляет за собой право ограничивать `потребителей` данного `ОЛ` в праве его использовать в случаях нарушения требований настоящей лицензии.
+
+`Трудящиеся` _обязаны_ не передавать права на настоящий `ОЛ` `капиталистам` и не препятствовать передаче этих же прав `трудящимся`, кроме случаев _явного_ использования `трудящимися` настоящего `ОЛ` в пользу `капиталистов`.
+
+В случае использования настоящего `ОЛ` `пользователи` автоматически принимают требования текущей УКЛ, и соглашаются со всеми положениями настоящих лицензионных требований.
+
+Настоящая лицензия _должна_ сопровождать `ОЛ`, в случае передачи отчуждаемых прав.
+
+## Защита лицензионных требований
+
+`Автор` может в любой момент изменить состав `ОЛ` в любых целях, кроме откровенно деструктивных, для защиты лицензионных требований.
+`Автор` может в любой момент изменить версию настоящих лицензионных требований, из-за внесённых им каких-либо изменений в `ОЛ`, но в рамках совместимости с предыдущими лицензионными требованиями.
+`Автор` может в любой момент отозвать отчуждаемые права (кроме особых случаев отчуждаемого права использования), если посчитает, что `потребитель` нарушает настоящие лицензионные требования.
+
+## Заключительные положения
+
+Если, какая-либо сторона настоящих лицензионных требований не оговорена или допускает какую-либо трактовку -- в таком случае, ситуация трактуется приоритетно в пользу `автора`, во вторую очередь в пользу `трудящихся` и никогда в пользу `капиталистов`. Данное требование не распространяется на особые случаи использования с отдельными договорённостями и только на основе свободного решения.

+ 76 - 0
vendor/gitp78su.ipnodns.ru/svi/kern/kc/helpers/helpers.go

@@ -0,0 +1,76 @@
+// package helpers -- содержит всякие полезняшки
+//
+// Пакет импортировать где нужно в нотации `. "gitlab.c2g.pw/back/uaj-abstract-client/pkg/helpers"`
+package helpers
+
+import (
+	"fmt"
+	"os"
+	"time"
+
+	. "gitp78su.ipnodns.ru/svi/kern/krn/kalias"
+)
+
+var (
+	IsStageLocal bool
+	IsStageProd  bool
+)
+
+// Assert -- проверка на правильность утверждения с падением в панику на локальном стенде (soft assert)
+func Assert(isCond bool, msgFormat string, args ...any) {
+	if isCond {
+		return
+	}
+	msg := fmt.Sprintf("SOFT ASSERT "+msgFormat+"\n", args...)
+	if IsStageLocal {
+		panic(msg)
+	}
+	fmt.Print(msg)
+}
+
+// Hassert -- проверка на правильность утверждения с безусловным падением в панику (hard assert)
+func Hassert(isCond bool, msgFormat string, args ...any) {
+	if isCond {
+		return
+	}
+	msg := fmt.Sprintf("HARD ASSERT "+msgFormat+"\n", args...)
+	panic(msg)
+}
+
+// TimeNowStr -- возвращает стандартную строку локального сейчас-времени "2006-01-02 15:04:05.000 -07 MST"
+func TimeNowStr() ATime {
+	strTime := time.Now().Local().Format("2006-01-02 15:04:05.000 -07 MST")
+	return ATime(strTime)
+}
+
+// TimeNow -- возвращает Unix сейчас-время (мсек, не зависит от положения)
+func TimeNow() int64 {
+	timeNow := time.Now().Local().UnixMilli()
+	return timeNow
+}
+
+// SleepMs -- спит миллисекунду
+func SleepMs() {
+	time.Sleep(time.Millisecond * 1)
+}
+
+func init_() {
+	strStage := os.Getenv("STAGE")
+	switch strStage {
+	case "local":
+		IsStageLocal = true
+		IsStageProd = false
+	case "prod":
+		IsStageProd = true
+		IsStageLocal = false
+	case "":
+		IsStageLocal = true
+		IsStageProd = false
+	default:
+		panic(fmt.Sprintf("lepers.init_(): unknown env STAGE (%v)\n", strStage))
+	}
+}
+
+func init() {
+	init_()
+}

+ 19 - 0
vendor/gitp78su.ipnodns.ru/svi/kern/krn/kalias/kalias.go

@@ -0,0 +1,19 @@
+// package kalias -- алиасы типов ядра
+package kalias
+
+// ATime -- метка времени
+//
+// Вывод: "2006-01-02 15:04:05.000 -07 MST")
+type ATime string
+
+// AStreamName -- имя потока для ожидания
+type AStreamName string
+
+// ATopic -- имя топика в шине
+type ATopic string
+
+// AHandlerName -- имя функции обработчика
+type AHandlerName string
+
+// AModuleName -- уникальное имя модуля
+type AModuleName string

+ 4 - 0
vendor/modules.txt

@@ -0,0 +1,4 @@
+# gitp78su.ipnodns.ru/svi/kern v1.16.0
+## explicit; go 1.24.2
+gitp78su.ipnodns.ru/svi/kern/kc/helpers
+gitp78su.ipnodns.ru/svi/kern/krn/kalias