1
0

matrix.go 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. package reedsolomon
  2. import "errors"
  3. type matrix []byte
  4. func genEncMatrixCauchy(d, p int) matrix {
  5. t := d + p
  6. m := make([]byte, t*d)
  7. for i := 0; i < d; i++ {
  8. m[i*d+i] = byte(1)
  9. }
  10. d2 := d * d
  11. for i := d; i < t; i++ {
  12. for j := 0; j < d; j++ {
  13. d := i ^ j
  14. a := inverseTbl[d]
  15. m[d2] = byte(a)
  16. d2++
  17. }
  18. }
  19. return m
  20. }
  21. func gfExp(b byte, n int) byte {
  22. if n == 0 {
  23. return 1
  24. }
  25. if b == 0 {
  26. return 0
  27. }
  28. a := logTbl[b]
  29. ret := int(a) * n
  30. for ret >= 255 {
  31. ret -= 255
  32. }
  33. return byte(expTbl[ret])
  34. }
  35. func genVandMatrix(vm []byte, t, d int) {
  36. for i := 0; i < t; i++ {
  37. for j := 0; j < d; j++ {
  38. vm[i*d+j] = gfExp(byte(i), j)
  39. }
  40. }
  41. }
  42. func (m matrix) mul(right matrix, rows, cols int, r []byte) {
  43. for i := 0; i < rows; i++ {
  44. for j := 0; j < cols; j++ {
  45. var v byte
  46. for k := 0; k < cols; k++ {
  47. v ^= gfMul(m[i*cols+k], right[k*cols+j])
  48. }
  49. r[i*cols+j] = v
  50. }
  51. }
  52. }
  53. func genEncMatrixVand(d, p int) (matrix, error) {
  54. t := d + p
  55. buf := make([]byte, (2*t+4*d)*d)
  56. vm := buf[:t*d]
  57. genVandMatrix(vm, t, d)
  58. top := buf[t*d : (t+d)*d]
  59. copy(top, vm[:d*d])
  60. raw := buf[(t+d)*d : (t+3*d)*d]
  61. im := buf[(t+3*d)*d : (t+4*d)*d]
  62. err := matrix(top).invert(raw, d, im)
  63. if err != nil {
  64. return nil, err
  65. }
  66. r := buf[(t+4*d)*d : (2*t+4*d)*d]
  67. matrix(vm).mul(im, t, d, r)
  68. return matrix(r), nil
  69. }
  70. // [I|m'] -> [m']
  71. func (m matrix) subMatrix(n int, r []byte) {
  72. for i := 0; i < n; i++ {
  73. off := i * n
  74. copy(r[off:off+n], m[2*off+n:2*(off+n)])
  75. }
  76. }
  77. func (m matrix) invert(raw matrix, n int, im []byte) error {
  78. // [m] -> [m|I]
  79. for i := 0; i < n; i++ {
  80. t := i * n
  81. copy(raw[2*t:2*t+n], m[t:t+n])
  82. raw[2*t+i+n] = byte(1)
  83. }
  84. err := gauss(raw, n)
  85. if err != nil {
  86. return err
  87. }
  88. raw.subMatrix(n, im)
  89. return nil
  90. }
  91. func (m matrix) swap(i, j, n int) {
  92. for k := 0; k < n; k++ {
  93. m[i*n+k], m[j*n+k] = m[j*n+k], m[i*n+k]
  94. }
  95. }
  96. func gfMul(a, b byte) byte {
  97. return mulTbl[a][b]
  98. }
  99. var errSingular = errors.New("rs.invert: matrix is singular")
  100. // [m|I] -> [I|m']
  101. func gauss(m matrix, n int) error {
  102. n2 := 2 * n
  103. for i := 0; i < n; i++ {
  104. if m[i*n2+i] == 0 {
  105. for j := i + 1; j < n; j++ {
  106. if m[j*n2+i] != 0 {
  107. m.swap(i, j, n2)
  108. break
  109. }
  110. }
  111. }
  112. if m[i*n2+i] == 0 {
  113. return errSingular
  114. }
  115. if m[i*n2+i] != 1 {
  116. d := m[i*n2+i]
  117. scale := inverseTbl[d]
  118. for c := 0; c < n2; c++ {
  119. m[i*n2+c] = gfMul(m[i*n2+c], scale)
  120. }
  121. }
  122. for j := i + 1; j < n; j++ {
  123. if m[j*n2+i] != 0 {
  124. scale := m[j*n2+i]
  125. for c := 0; c < n2; c++ {
  126. m[j*n2+c] ^= gfMul(scale, m[i*n2+c])
  127. }
  128. }
  129. }
  130. }
  131. for k := 0; k < n; k++ {
  132. for j := 0; j < k; j++ {
  133. if m[j*n2+k] != 0 {
  134. scale := m[j*n2+k]
  135. for c := 0; c < n2; c++ {
  136. m[j*n2+c] ^= gfMul(scale, m[k*n2+c])
  137. }
  138. }
  139. }
  140. }
  141. return nil
  142. }