// 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 сам.ключСтарш, сам.ключМладш }