errorcorrection.go 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. package aztec
  2. import (
  3. "github.com/boombuler/barcode/utils"
  4. )
  5. func bitsToWords(stuffedBits *utils.BitList, wordSize int, wordCount int) []int {
  6. message := make([]int, wordCount)
  7. for i := 0; i < wordCount; i++ {
  8. value := 0
  9. for j := 0; j < wordSize; j++ {
  10. if stuffedBits.GetBit(i*wordSize + j) {
  11. value |= (1 << uint(wordSize-j-1))
  12. }
  13. }
  14. message[i] = value
  15. }
  16. return message
  17. }
  18. func generateCheckWords(bits *utils.BitList, totalBits, wordSize int) *utils.BitList {
  19. rs := utils.NewReedSolomonEncoder(getGF(wordSize))
  20. // bits is guaranteed to be a multiple of the wordSize, so no padding needed
  21. messageWordCount := bits.Len() / wordSize
  22. totalWordCount := totalBits / wordSize
  23. eccWordCount := totalWordCount - messageWordCount
  24. messageWords := bitsToWords(bits, wordSize, messageWordCount)
  25. eccWords := rs.Encode(messageWords, eccWordCount)
  26. startPad := totalBits % wordSize
  27. messageBits := new(utils.BitList)
  28. messageBits.AddBits(0, byte(startPad))
  29. for _, messageWord := range messageWords {
  30. messageBits.AddBits(messageWord, byte(wordSize))
  31. }
  32. for _, eccWord := range eccWords {
  33. messageBits.AddBits(eccWord, byte(wordSize))
  34. }
  35. return messageBits
  36. }
  37. func getGF(wordSize int) *utils.GaloisField {
  38. switch wordSize {
  39. case 4:
  40. return utils.NewGaloisField(0x13, 16, 1)
  41. case 6:
  42. return utils.NewGaloisField(0x43, 64, 1)
  43. case 8:
  44. return utils.NewGaloisField(0x012D, 256, 1)
  45. case 10:
  46. return utils.NewGaloisField(0x409, 1024, 1)
  47. case 12:
  48. return utils.NewGaloisField(0x1069, 4096, 1)
  49. default:
  50. return nil
  51. }
  52. }