// Encode returns a code39 barcode for the given content // if includeChecksum is set to true, a checksum character is calculated and added to the content func Encode(content string, includeChecksum bool, fullASCIIMode bool) (barcode.Barcode, error) { if fullASCIIMode { var err error content, err = prepare(content) if err != nil { return nil, err } } else if strings.ContainsRune(content, '*') { return nil, errors.New("invalid data! try full ascii mode") } data := "*" + content if includeChecksum { data += getChecksum(content) } data += "*" result := new(utils.BitList) for i, r := range data { if i != 0 { result.AddBit(false) } info, ok := encodeTable[r] if !ok { return nil, errors.New("invalid data! try full ascii mode") } result.AddBit(info.data...) } return utils.New1DCode("Code 39", content, result), nil }
func encodeEAN13(code string) *utils.BitList { result := new(utils.BitList) result.AddBit(true, false, true) var firstNum []bool for cpos, r := range code { num, ok := encoderTable[r] if !ok { return nil } if cpos == 0 { firstNum = num.CheckSum continue } var data []bool if cpos < 7 { // Left if firstNum[cpos-1] { data = num.LeftEven } else { data = num.LeftOdd } } else { data = num.Right } if cpos == 7 { result.AddBit(false, true, false, true, false) } result.AddBit(data...) } result.AddBit(true, false, true) return result }
func encodeEAN8(code string) *utils.BitList { result := new(utils.BitList) result.AddBit(true, false, true) for cpos, r := range code { num, ok := encoderTable[r] if !ok { return nil } var data []bool if cpos < 4 { data = num.LeftOdd } else { data = num.Right } if cpos == 4 { result.AddBit(false, true, false, true, false) } result.AddBit(data...) } result.AddBit(true, false, true) return result }
// Encode creates a codabar barcode for the given content func Encode(content string, interleaved bool) (barcode.Barcode, error) { if content == "" { return nil, errors.New("content is empty") } if interleaved && len(content)%2 == 1 { return nil, errors.New("can only encode even number of digits in interleaved mode") } mode := modes[interleaved] resBits := new(utils.BitList) resBits.AddBit(mode.start...) var lastRune *rune for _, r := range content { var a, b pattern if interleaved { if lastRune == nil { lastRune = new(rune) *lastRune = r continue } else { var o1, o2 bool a, o1 = encodingTable[*lastRune] b, o2 = encodingTable[r] if !o1 || !o2 { return nil, fmt.Errorf("can not encode \"%s\"", content) } lastRune = nil } } else { var ok bool a, ok = encodingTable[r] if !ok { return nil, fmt.Errorf("can not encode \"%s\"", content) } b = nonInterleavedSpace } for i := 0; i < patternWidth; i++ { for x := 0; x < mode.widths[a[i]]; x++ { resBits.AddBit(true) } for x := 0; x < mode.widths[b[i]]; x++ { resBits.AddBit(false) } } } resBits.AddBit(mode.end...) kindTxt := "" if interleaved { kindTxt = " (interleaved)" } return utils.New1DCode("2 of 5"+kindTxt, content, resBits, -1), nil }
// Encode creates a codabar barcode for the given content func Encode(content string) (barcode.Barcode, error) { checkValid, _ := regexp.Compile(`[ABCD][0123456789\-\$\:/\.\+]*[ABCD]$`) if content == "!" || checkValid.ReplaceAllString(content, "!") != "!" { return nil, fmt.Errorf("can not encode \"%s\"", content) } resBits := new(utils.BitList) for i, r := range content { if i > 0 { resBits.AddBit(false) } resBits.AddBit(encodingTable[r]...) } return utils.New1DCode("Codabar", content, resBits), nil }
func Encode(content string) (barcode.Barcode, error) { contentRunes := strToRunes(content) if len(contentRunes) < 0 || len(contentRunes) > 80 { return nil, fmt.Errorf("content length should be between 1 and 80 runes but got %d", len(contentRunes)) } idxList := getCodeIndexList(contentRunes) if idxList == nil { return nil, fmt.Errorf("\"%s\" could not be encoded", content) } result := new(utils.BitList) sum := 0 for i, idx := range idxList.GetBytes() { if i == 0 { sum = int(idx) } else { sum += i * int(idx) } result.AddBit(encodingTable[idx]...) } result.AddBit(encodingTable[sum%103]...) result.AddBit(encodingTable[stopSymbol]...) return utils.New1DCode("Code 128", content, result), nil }
func encodeAlphaNumeric(content string, ecl ErrorCorrectionLevel) (*utils.BitList, *versionInfo, error) { contentLenIsOdd := len(content)%2 == 1 contentBitCount := (len(content) / 2) * 11 if contentLenIsOdd { contentBitCount += 6 } vi := findSmallestVersionInfo(ecl, alphaNumericMode, contentBitCount) if vi == nil { return nil, nil, errors.New("To much data to encode") } res := new(utils.BitList) res.AddBits(int(alphaNumericMode), 4) res.AddBits(len(content), vi.charCountBits(alphaNumericMode)) encoder := stringToAlphaIdx(content) for idx := 0; idx < len(content)/2; idx++ { c1 := <-encoder c2 := <-encoder if c1 < 0 || c2 < 0 { return nil, nil, fmt.Errorf("\"%s\" can not be encoded as %s", content, AlphaNumeric) } res.AddBits(c1*45+c2, 11) } if contentLenIsOdd { c := <-encoder if c < 0 { return nil, nil, fmt.Errorf("\"%s\" can not be encoded as %s", content, AlphaNumeric) } res.AddBits(c, 6) } addPaddingAndTerminator(res, vi) return res, vi, nil }
func encodeNumeric(content string, ecl ErrorCorrectionLevel) (*utils.BitList, *versionInfo, error) { contentBitCount := (len(content) / 3) * 10 switch len(content) % 3 { case 1: contentBitCount += 4 case 2: contentBitCount += 7 } vi := findSmallestVersionInfo(ecl, numericMode, contentBitCount) if vi == nil { return nil, nil, errors.New("To much data to encode") } res := new(utils.BitList) res.AddBits(int(numericMode), 4) res.AddBits(len(content), vi.charCountBits(numericMode)) for pos := 0; pos < len(content); pos += 3 { var curStr string if pos+3 <= len(content) { curStr = content[pos : pos+3] } else { curStr = content[pos:] } i, err := strconv.Atoi(curStr) if err != nil || i < 0 { return nil, nil, fmt.Errorf("\"%s\" can not be encoded as %s", content, Numeric) } var bitCnt byte switch len(curStr) % 3 { case 0: bitCnt = 10 case 1: bitCnt = 4 break case 2: bitCnt = 7 break } res.AddBits(i, bitCnt) } addPaddingAndTerminator(res, vi) return res, vi, nil }
func encodeUnicode(content string, ecl ErrorCorrectionLevel) (*utils.BitList, *versionInfo, error) { data := []byte(content) vi := findSmallestVersionInfo(ecl, byteMode, len(data)*8) if vi == nil { return nil, nil, errors.New("To much data to encode") } // It's not correct to add the unicode bytes to the result directly but most readers can't handle the // required ECI header... res := new(utils.BitList) res.AddBits(int(byteMode), 4) res.AddBits(len(content), vi.charCountBits(byteMode)) for _, b := range data { res.AddByte(b) } addPaddingAndTerminator(res, vi) return res, vi, nil }
func getCodeIndexList(content []rune) *utils.BitList { result := new(utils.BitList) curEncoding := byte(0) for i := 0; i < len(content); i++ { if shouldUseCTable(content[i:], curEncoding) { if curEncoding != startCSymbol { result.AddByte(startCSymbol) curEncoding = startCSymbol } idx := (content[i] - '0') * 10 i++ idx = idx + (content[i] - '0') result.AddByte(byte(idx)) } else { if curEncoding != startBSymbol { result.AddByte(startBSymbol) curEncoding = startBSymbol } idx := strings.IndexRune(bTable, content[i]) if idx < 0 { return nil } result.AddByte(byte(idx)) } } fmt.Println(result.GetBytes()) return result }
func getCodeIndexList(content []rune) *utils.BitList { result := new(utils.BitList) curEncoding := byte(0) for i := 0; i < len(content); i++ { if shouldUseCTable(content[i:], curEncoding) { if curEncoding != startCSymbol { if curEncoding == byte(0) { result.AddByte(startCSymbol) } else { result.AddByte(codeCSymbol) } curEncoding = startCSymbol } idx := (content[i] - '0') * 10 i++ idx = idx + (content[i] - '0') result.AddByte(byte(idx)) } else { if curEncoding != startBSymbol { if curEncoding == byte(0) { result.AddByte(startBSymbol) } else { result.AddByte(codeBSymbol) } curEncoding = startBSymbol } var idx int switch content[i] { case FNC1: idx = 102 break case FNC2: idx = 97 break case FNC3: idx = 96 break case FNC4: idx = 100 break default: idx = strings.IndexRune(bTable, content[i]) break } if idx < 0 { return nil } result.AddByte(byte(idx)) } } return result }
func addPaddingAndTerminator(bl *utils.BitList, vi *versionInfo) { for i := 0; i < 4 && bl.Len() < vi.totalDataBytes()*8; i++ { bl.AddBit(false) } for bl.Len()%8 != 0 { bl.AddBit(false) } for i := 0; bl.Len() < vi.totalDataBytes()*8; i++ { if i%2 == 0 { bl.AddByte(236) } else { bl.AddByte(17) } } }