cipher_rc4.go 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. package qmc
  2. import (
  3. "errors"
  4. )
  5. // A rc4Cipher is an instance of RC4 using a particular key.
  6. type rc4Cipher struct {
  7. box []byte
  8. key []byte
  9. hash uint32
  10. n int
  11. }
  12. // newRC4Cipher creates and returns a new rc4Cipher. The key argument should be the
  13. // RC4 key, at least 1 byte and at most 256 bytes.
  14. func newRC4Cipher(key []byte) (*rc4Cipher, error) {
  15. n := len(key)
  16. if n == 0 {
  17. return nil, errors.New("qmc/cipher_rc4: invalid key size")
  18. }
  19. var c = rc4Cipher{key: key, n: n}
  20. c.box = make([]byte, n)
  21. for i := 0; i < n; i++ {
  22. c.box[i] = byte(i)
  23. }
  24. var j = 0
  25. for i := 0; i < n; i++ {
  26. j = (j + int(c.box[i]) + int(key[i%n])) % n
  27. c.box[i], c.box[j] = c.box[j], c.box[i]
  28. }
  29. c.getHashBase()
  30. return &c, nil
  31. }
  32. func (c *rc4Cipher) getHashBase() {
  33. c.hash = 1
  34. for i := 0; i < c.n; i++ {
  35. v := uint32(c.key[i])
  36. if v == 0 {
  37. continue
  38. }
  39. nextHash := c.hash * v
  40. if nextHash == 0 || nextHash <= c.hash {
  41. break
  42. }
  43. c.hash = nextHash
  44. }
  45. }
  46. const (
  47. rc4SegmentSize = 5120
  48. rc4FirstSegmentSize = 128
  49. )
  50. func (c *rc4Cipher) Decrypt(src []byte, offset int) {
  51. toProcess := len(src)
  52. processed := 0
  53. markProcess := func(p int) (finished bool) {
  54. offset += p
  55. toProcess -= p
  56. processed += p
  57. return toProcess == 0
  58. }
  59. if offset < rc4FirstSegmentSize {
  60. blockSize := toProcess
  61. if blockSize > rc4FirstSegmentSize-offset {
  62. blockSize = rc4FirstSegmentSize - offset
  63. }
  64. c.encFirstSegment(src[:blockSize], offset)
  65. if markProcess(blockSize) {
  66. return
  67. }
  68. }
  69. if offset%rc4SegmentSize != 0 {
  70. blockSize := toProcess
  71. if blockSize > rc4SegmentSize-offset%rc4SegmentSize {
  72. blockSize = rc4SegmentSize - offset%rc4SegmentSize
  73. }
  74. c.encASegment(src[processed:processed+blockSize], offset)
  75. if markProcess(blockSize) {
  76. return
  77. }
  78. }
  79. for toProcess > rc4SegmentSize {
  80. c.encASegment(src[processed:processed+rc4SegmentSize], offset)
  81. markProcess(rc4SegmentSize)
  82. }
  83. if toProcess > 0 {
  84. c.encASegment(src[processed:], offset)
  85. }
  86. }
  87. func (c *rc4Cipher) encFirstSegment(buf []byte, offset int) {
  88. for i := 0; i < len(buf); i++ {
  89. buf[i] ^= c.key[c.getSegmentSkip(offset+i)]
  90. }
  91. }
  92. func (c *rc4Cipher) encASegment(buf []byte, offset int) {
  93. box := make([]byte, c.n)
  94. copy(box, c.box)
  95. j, k := 0, 0
  96. skipLen := (offset % rc4SegmentSize) + c.getSegmentSkip(offset/rc4SegmentSize)
  97. for i := -skipLen; i < len(buf); i++ {
  98. j = (j + 1) % c.n
  99. k = (int(box[j]) + k) % c.n
  100. box[j], box[k] = box[k], box[j]
  101. if i >= 0 {
  102. buf[i] ^= box[(int(box[j])+int(box[k]))%c.n]
  103. }
  104. }
  105. }
  106. func (c *rc4Cipher) getSegmentSkip(id int) int {
  107. seed := int(c.key[id%c.n])
  108. idx := int64(float64(c.hash) / float64((id+1)*seed) * 100.0)
  109. return int(idx % int64(c.n))
  110. }