git.sr.ht/~pingoo/stdx@v0.0.0-20240218134121-094174641f6e/barcode/qr/alphanumeric.go (about)

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