app.go 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. package main
  2. import (
  3. "math/rand"
  4. "sort"
  5. "unicode"
  6. )
  7. func encodeWord(word []rune, wordLength int) {
  8. if wordLength == 4 {
  9. word[1], word[2] = word[2], word[1]
  10. return
  11. }
  12. original := string(word)
  13. toShuffle := word[1 : wordLength-1]
  14. toShuffleLength := wordLength - 2
  15. rand.Shuffle(toShuffleLength, func(i, j int) {
  16. toShuffle[i], toShuffle[j] = toShuffle[j], toShuffle[i]
  17. })
  18. if string(word) == original {
  19. rand.Shuffle(toShuffleLength, func(i, j int) {
  20. toShuffle[i], toShuffle[j] = toShuffle[j], toShuffle[i]
  21. })
  22. }
  23. }
  24. //EncodeText returns encoded provided text and sorted array of encoded words
  25. func EncodeText(text []rune) (string, []string) {
  26. var currentWord []rune
  27. var newString []rune
  28. var encodedWords []string
  29. for _, item := range text {
  30. if unicode.IsPunct(item) || unicode.IsSpace(item) {
  31. currentWordLength := len(currentWord)
  32. if currentWordLength >= 4 {
  33. beforeEncoding := string(currentWord)
  34. encodeWord(currentWord, currentWordLength)
  35. if string(currentWord) != beforeEncoding {
  36. encodedWords = append(encodedWords, beforeEncoding)
  37. }
  38. }
  39. for _, letter := range currentWord {
  40. newString = append(newString, letter)
  41. }
  42. currentWord = []rune{}
  43. newString = append(newString, item)
  44. continue
  45. }
  46. currentWord = append(currentWord, item)
  47. }
  48. sort.Strings(encodedWords)
  49. return string(newString), encodedWords
  50. }
  51. func removeString(array []string, index int) []string {
  52. return append(array[:index], array[index+1:]...)
  53. }
  54. func removeRune(array []rune, index int) []rune {
  55. return append(array[:index], array[index+1:]...)
  56. }
  57. func decodeWord(word []rune, wordLength int, encodedWords []string) (string, []string) {
  58. for index, encodedWord := range encodedWords {
  59. if len(encodedWord) != wordLength {
  60. continue
  61. }
  62. encoded := []rune(encodedWord)
  63. if word[0] != encoded[0] && word[wordLength-1] != encoded[wordLength-1] {
  64. continue
  65. }
  66. found := false
  67. partOfEncoded := encoded[1 : wordLength-1]
  68. for i := 1; i < wordLength-1; i++ {
  69. for j, letter := range partOfEncoded {
  70. if letter == word[i] {
  71. partOfEncoded = removeRune(partOfEncoded, j)
  72. found = true
  73. break
  74. }
  75. }
  76. if !found {
  77. break
  78. }
  79. }
  80. if found {
  81. return encodedWord, removeString(encodedWords, index)
  82. }
  83. }
  84. return string(word), encodedWords
  85. }
  86. //DecodeText returns decoded provided text using provided array of encoded words
  87. func DecodeText(text []rune, encodedWords []string) string {
  88. var currentWord []rune
  89. var newString []rune
  90. for _, item := range text {
  91. if unicode.IsPunct(item) || unicode.IsSpace(item) {
  92. currentWordLength := len(currentWord)
  93. if currentWordLength >= 4 {
  94. var decoded string
  95. decoded, encodedWords = decodeWord(currentWord, currentWordLength, encodedWords)
  96. currentWord = []rune(decoded)
  97. }
  98. for _, letter := range currentWord {
  99. newString = append(newString, letter)
  100. }
  101. currentWord = []rune{}
  102. newString = append(newString, item)
  103. continue
  104. }
  105. currentWord = append(currentWord, item)
  106. }
  107. return string(newString)
  108. }