app.go 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. package weirdtext
  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 string) EncodedText {
  26. runes := []rune(text)
  27. var currentWord []rune
  28. var newString []rune
  29. var encodedWords []string
  30. for _, item := range runes {
  31. if unicode.IsPunct(item) || unicode.IsSpace(item) {
  32. currentWordLength := len(currentWord)
  33. if currentWordLength >= 4 {
  34. beforeEncoding := string(currentWord)
  35. encodeWord(currentWord, currentWordLength)
  36. if string(currentWord) != beforeEncoding {
  37. encodedWords = append(encodedWords, beforeEncoding)
  38. }
  39. }
  40. for _, letter := range currentWord {
  41. newString = append(newString, letter)
  42. }
  43. currentWord = []rune{}
  44. newString = append(newString, item)
  45. continue
  46. }
  47. currentWord = append(currentWord, item)
  48. }
  49. sort.Strings(encodedWords)
  50. return EncodedText{string(newString), encodedWords}
  51. }
  52. func removeString(array []string, index int) []string {
  53. return append(array[:index], array[index+1:]...)
  54. }
  55. func removeRune(array []rune, index int) []rune {
  56. return append(array[:index], array[index+1:]...)
  57. }
  58. func decodeWord(word []rune, wordLength int, encodedWords []string) (string, []string) {
  59. for index, encodedWord := range encodedWords {
  60. encoded := []rune(encodedWord)
  61. if len(encoded) != wordLength {
  62. continue
  63. }
  64. if word[0] != encoded[0] || word[wordLength-1] != encoded[wordLength-1] {
  65. continue
  66. }
  67. found := false
  68. partOfEncoded := encoded[1 : wordLength-1]
  69. for i := 1; i < wordLength-1; i++ {
  70. for j, letter := range partOfEncoded {
  71. if letter == word[i] {
  72. partOfEncoded = removeRune(partOfEncoded, j)
  73. found = true
  74. break
  75. }
  76. }
  77. if !found {
  78. break
  79. }
  80. }
  81. if found {
  82. return encodedWord, removeString(encodedWords, index)
  83. }
  84. }
  85. return string(word), encodedWords
  86. }
  87. //DecodeText returns decoded provided text using provided array of encoded words
  88. func DecodeText(encoded EncodedText) string {
  89. runes := []rune(encoded.Text)
  90. encodedWords := make([]string, len(encoded.EncodedWords))
  91. copy(encodedWords, encoded.EncodedWords)
  92. var currentWord []rune
  93. var newString []rune
  94. for _, item := range runes {
  95. if unicode.IsPunct(item) || unicode.IsSpace(item) {
  96. currentWordLength := len(currentWord)
  97. if currentWordLength >= 4 {
  98. var decoded string
  99. decoded, encodedWords = decodeWord(currentWord, currentWordLength, encodedWords)
  100. currentWord = []rune(decoded)
  101. }
  102. for _, letter := range currentWord {
  103. newString = append(newString, letter)
  104. }
  105. currentWord = []rune{}
  106. newString = append(newString, item)
  107. continue
  108. }
  109. currentWord = append(currentWord, item)
  110. }
  111. return string(newString)
  112. }