| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126 |
- // package Частотник -- ищет минимально частотную пару
- package frequencer
- import (
- "fmt"
- "log"
- "time"
- // . "gitp78su.ipnodns.ru/svi/kern/v3/kc/helpers"
- "gitp78su.ipnodns.ru/svi/packer/lev0/types"
- "gitp78su.ipnodns.ru/svi/packer/lev1/dict_keys"
- "gitp78su.ipnodns.ru/svi/packer/lev2/belt"
- )
- // Частотник -- ищет минимально частотную пару
- type Частотник struct {
- лента *belt.Лента
- словКлючи *dict_keys.СловКлючи
- ключСтарш, ключМладш uint32 // Частотные ключи
- ключиСтарые map[uint32]bool // Перебранные комбинации для key0
- }
- // НовЧастотник -- возвращает новый минимальный искатель
- func НовЧастотник() *Частотник {
- сам := &Частотник{
- ключиСтарые: map[uint32]bool{},
- словКлючи: dict_keys.СловКлючиПолуч(),
- лента: belt.ЛентаПолуч(),
- }
- _ = types.ИЧастотник(сам)
- return сам
- }
- func (сам *Частотник) еслиПараЕсть(ключСтарш, ключМладш uint32) bool {
- число := ключСтарш*65536 + ключМладш
- _, isOk := сам.ключиСтарые[число]
- return isOk
- }
- // Пуск -- запускает вычисление частотной пары
- //
- // Считается успехом, если нашёл 5 замен словарных ключей
- func (сам *Частотник) Пуск() error {
- списКлючи := сам.словКлючи.Ключи()
- if len(списКлючи) <= 1 {
- return fmt.Errorf("Частотник.Пуск(): lstKeys is empty")
- }
- ключСтарш := uint32(0)
- ключМладш := uint32(0)
- binData := сам.лента.Вых()
- число := uint32(0)
- фнКлючДоб := func() {
- число = uint32(ключСтарш)*65536 + uint32(ключМладш)
- сам.ключиСтарые[число] = true
- }
- счёт := 0
- значСтарш := uint32(0)
- фнСравнить := func(инд int) {
- значМладш := binData[инд]
- if значСтарш != ключСтарш {
- return
- }
- if значМладш != ключМладш {
- return
- }
- счёт++
- if инд >= len(binData) {
- return
- }
- значСтарш = binData[инд]
- }
- фнКлюч1 := func() bool { // Ищет совпадение для ключСтарш и ключМладш
- времНач := time.Now().UnixMilli() // Для ограничения времени поиска бесполезной комбинации
- for _, ключМладш = range списКлючи {
- if сам.еслиПараЕсть(ключСтарш, ключМладш) {
- continue
- }
- счёт = 0
- значСтарш = binData[0]
- счётВызов := 0
- for инд_ := 1; инд_ < len(binData); инд_++ {
- значМладш := binData[инд_]
- фнСравнить(инд_)
- счётВызов++
- if счётВызов > 5000 {
- timeDelta := time.Now().UnixMilli() - времНач
- if timeDelta > 100 {
- фнКлючДоб()
- return false
- }
- счётВызов = 0
- }
- if счёт >= 10 {
- фнКлючДоб()
- времДельта := time.Now().UnixMilli() - времНач
- log.Printf("Частотник.fnKey1(): timeDelta=%v msec\n", времДельта)
- return true
- }
- значСтарш = значМладш
- }
- фнКлючДоб()
- }
- return false
- }
- еслиНайдено := false
- for _, ключСтарш = range списКлючи {
- if фнКлюч1() {
- еслиНайдено = true
- break
- }
- }
- if !еслиНайдено {
- return fmt.Errorf("Частотник.Пуск(): not find keys for change, checked=%v", len(сам.ключиСтарые))
- }
- сам.ключСтарш = ключСтарш
- сам.ключМладш = ключМладш
- log.Printf("Частотник.Пуск(): ключи=[%v %v], checked=%v\n", сам.ключСтарш, сам.ключМладш, len(сам.ключиСтарые))
- return nil
- }
- // Ключи -- возвращает найденные ключи
- func (сам *Частотник) Ключи() (uint32, uint32) {
- return сам.ключСтарш, сам.ключМладш
- }
|