alphanumeric.go 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. package qr
  2. import (
  3. "errors"
  4. "fmt"
  5. "strings"
  6. "github.com/boombuler/barcode/utils"
  7. )
  8. const charSet string = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:"
  9. func stringToAlphaIdx(content string) <-chan int {
  10. result := make(chan int)
  11. go func() {
  12. for _, r := range content {
  13. idx := strings.IndexRune(charSet, r)
  14. result <- idx
  15. if idx < 0 {
  16. break
  17. }
  18. }
  19. close(result)
  20. }()
  21. return result
  22. }
  23. func encodeAlphaNumeric(content string, ecl ErrorCorrectionLevel) (*utils.BitList, *versionInfo, error) {
  24. contentLenIsOdd := len(content)%2 == 1
  25. contentBitCount := (len(content) / 2) * 11
  26. if contentLenIsOdd {
  27. contentBitCount += 6
  28. }
  29. vi := findSmallestVersionInfo(ecl, alphaNumericMode, contentBitCount)
  30. if vi == nil {
  31. return nil, nil, errors.New("To much data to encode")
  32. }
  33. res := new(utils.BitList)
  34. res.AddBits(int(alphaNumericMode), 4)
  35. res.AddBits(len(content), vi.charCountBits(alphaNumericMode))
  36. encoder := stringToAlphaIdx(content)
  37. for idx := 0; idx < len(content)/2; idx++ {
  38. c1 := <-encoder
  39. c2 := <-encoder
  40. if c1 < 0 || c2 < 0 {
  41. return nil, nil, fmt.Errorf("\"%s\" can not be encoded as %s", content, AlphaNumeric)
  42. }
  43. res.AddBits(c1*45+c2, 11)
  44. }
  45. if contentLenIsOdd {
  46. c := <-encoder
  47. if c < 0 {
  48. return nil, nil, fmt.Errorf("\"%s\" can not be encoded as %s", content, AlphaNumeric)
  49. }
  50. res.AddBits(c, 6)
  51. }
  52. addPaddingAndTerminator(res, vi)
  53. return res, vi, nil
  54. }