frequencer.go 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. // package Частотник -- ищет минимально частотную пару
  2. package frequencer
  3. import (
  4. "fmt"
  5. "log"
  6. "time"
  7. // . "gitp78su.ipnodns.ru/svi/kern/v3/kc/helpers"
  8. "gitp78su.ipnodns.ru/svi/packer/lev0/types"
  9. "gitp78su.ipnodns.ru/svi/packer/lev1/dict_keys"
  10. "gitp78su.ipnodns.ru/svi/packer/lev2/belt"
  11. )
  12. // Частотник -- ищет минимально частотную пару
  13. type Частотник struct {
  14. лента *belt.Лента
  15. словКлючи *dict_keys.СловКлючи
  16. ключСтарш, ключМладш uint32 // Частотные ключи
  17. ключиСтарые map[uint32]bool // Перебранные комбинации для key0
  18. }
  19. // НовЧастотник -- возвращает новый минимальный искатель
  20. func НовЧастотник() *Частотник {
  21. сам := &Частотник{
  22. ключиСтарые: map[uint32]bool{},
  23. словКлючи: dict_keys.СловКлючиПолуч(),
  24. лента: belt.ЛентаПолуч(),
  25. }
  26. _ = types.ИЧастотник(сам)
  27. return сам
  28. }
  29. func (сам *Частотник) еслиПараЕсть(ключСтарш, ключМладш uint32) bool {
  30. число := ключСтарш*65536 + ключМладш
  31. _, isOk := сам.ключиСтарые[число]
  32. return isOk
  33. }
  34. // Пуск -- запускает вычисление частотной пары
  35. //
  36. // Считается успехом, если нашёл 5 замен словарных ключей
  37. func (сам *Частотник) Пуск() error {
  38. списКлючи := сам.словКлючи.Ключи()
  39. if len(списКлючи) <= 1 {
  40. return fmt.Errorf("Частотник.Пуск(): lstKeys is empty")
  41. }
  42. ключСтарш := uint32(0)
  43. ключМладш := uint32(0)
  44. binData := сам.лента.Вых()
  45. число := uint32(0)
  46. фнКлючДоб := func() {
  47. число = uint32(ключСтарш)*65536 + uint32(ключМладш)
  48. сам.ключиСтарые[число] = true
  49. }
  50. счёт := 0
  51. значСтарш := uint32(0)
  52. фнСравнить := func(инд int) {
  53. значМладш := binData[инд]
  54. if значСтарш != ключСтарш {
  55. return
  56. }
  57. if значМладш != ключМладш {
  58. return
  59. }
  60. счёт++
  61. if инд >= len(binData) {
  62. return
  63. }
  64. значСтарш = binData[инд]
  65. }
  66. фнКлюч1 := func() bool { // Ищет совпадение для ключСтарш и ключМладш
  67. времНач := time.Now().UnixMilli() // Для ограничения времени поиска бесполезной комбинации
  68. for _, ключМладш = range списКлючи {
  69. if сам.еслиПараЕсть(ключСтарш, ключМладш) {
  70. continue
  71. }
  72. счёт = 0
  73. значСтарш = binData[0]
  74. счётВызов := 0
  75. for инд_ := 1; инд_ < len(binData); инд_++ {
  76. значМладш := binData[инд_]
  77. фнСравнить(инд_)
  78. счётВызов++
  79. if счётВызов > 5000 {
  80. timeDelta := time.Now().UnixMilli() - времНач
  81. if timeDelta > 100 {
  82. фнКлючДоб()
  83. return false
  84. }
  85. счётВызов = 0
  86. }
  87. if счёт >= 10 {
  88. фнКлючДоб()
  89. времДельта := time.Now().UnixMilli() - времНач
  90. log.Printf("Частотник.fnKey1(): timeDelta=%v msec\n", времДельта)
  91. return true
  92. }
  93. значСтарш = значМладш
  94. }
  95. фнКлючДоб()
  96. }
  97. return false
  98. }
  99. еслиНайдено := false
  100. for _, ключСтарш = range списКлючи {
  101. if фнКлюч1() {
  102. еслиНайдено = true
  103. break
  104. }
  105. }
  106. if !еслиНайдено {
  107. return fmt.Errorf("Частотник.Пуск(): not find keys for change, checked=%v", len(сам.ключиСтарые))
  108. }
  109. сам.ключСтарш = ключСтарш
  110. сам.ключМладш = ключМладш
  111. log.Printf("Частотник.Пуск(): ключи=[%v %v], checked=%v\n", сам.ключСтарш, сам.ключМладш, len(сам.ключиСтарые))
  112. return nil
  113. }
  114. // Ключи -- возвращает найденные ключи
  115. func (сам *Частотник) Ключи() (uint32, uint32) {
  116. return сам.ключСтарш, сам.ключМладш
  117. }