// encodeDataRaw encodes data in dataMode. The encoded data is appended to // encoded. func (d *dataEncoder) encodeDataRaw(data []byte, dataMode dataMode, encoded *bitset.Bitset) { modeIndicator := d.modeIndicator(dataMode) charCountBits := d.charCountBits(dataMode) // Append mode indicator. encoded.Append(modeIndicator) // Append character count. encoded.AppendUint32(uint32(len(data)), charCountBits) // Append data. switch dataMode { case dataModeNumeric: for i := 0; i < len(data); i += 3 { charsRemaining := len(data) - i var value uint32 bitsUsed := 1 for j := 0; j < charsRemaining && j < 3; j++ { value *= 10 value += uint32(data[i+j] - 0x30) bitsUsed += 3 } encoded.AppendUint32(value, bitsUsed) } case dataModeAlphanumeric: for i := 0; i < len(data); i += 2 { charsRemaining := len(data) - i var value uint32 for j := 0; j < charsRemaining && j < 2; j++ { value *= 45 value += encodeAlphanumericCharacter(data[i+j]) } bitsUsed := 6 if charsRemaining > 1 { bitsUsed = 11 } encoded.AppendUint32(value, bitsUsed) } case dataModeByte: for _, b := range data { encoded.AppendByte(b, 8) } } }
// New constructs a QRCode. // // var q *qrcode.QRCode // q, err := qrcode.New("my content", qrcode.Medium) // // An error occurs if the content is too long. func New(content string, level RecoveryLevel) (*QRCode, error) { encoders := []dataEncoderType{dataEncoderType1To9, dataEncoderType10To26, dataEncoderType27To40} var encoder *dataEncoder var encoded *bitset.Bitset var chosenVersion *qrCodeVersion var err error for _, t := range encoders { encoder = newDataEncoder(t) encoded, err = encoder.encode([]byte(content)) if err != nil { continue } chosenVersion = chooseQRCodeVersion(level, encoder, encoded.Len()) if chosenVersion != nil { break } } if err != nil { return nil, err } else if chosenVersion == nil { return nil, errors.New("content too long to encode") } q := &QRCode{ Content: content, Level: level, VersionNumber: chosenVersion.version, ForegroundColor: color.Black, BackgroundColor: color.White, encoder: encoder, data: encoded, version: *chosenVersion, } q.encode(chosenVersion.numTerminatorBitsRequired(encoded.Len())) return q, nil }
func newWithForcedVersion(content string, version int, level RecoveryLevel) (*QRCode, error) { var encoder *dataEncoder switch { case version >= 1 && version <= 9: encoder = newDataEncoder(dataEncoderType1To9) case version >= 10 && version <= 26: encoder = newDataEncoder(dataEncoderType10To26) case version >= 27 && version <= 40: encoder = newDataEncoder(dataEncoderType27To40) default: log.Fatalf("Invalid version %d (expected 1-40 inclusive)", version) } var encoded *bitset.Bitset encoded, err := encoder.encode([]byte(content)) if err != nil { return nil, err } chosenVersion := getQRCodeVersion(level, version) if chosenVersion == nil { return nil, errors.New("cannot find QR Code version") } q := &QRCode{ Content: content, Level: level, VersionNumber: chosenVersion.version, ForegroundColor: color.Black, BackgroundColor: color.White, encoder: encoder, data: encoded, version: *chosenVersion, } q.encode(chosenVersion.numTerminatorBitsRequired(encoded.Len())) return q, nil }
// newGFPolyFromData returns |data| as a polynomial over GF(2^8). // // Each data byte becomes the coefficient of an x term. // // For an n byte input the polynomial is: // data[n-1]*(x^n-1) + data[n-2]*(x^n-2) ... + data[0]*(x^0). func newGFPolyFromData(data *bitset.Bitset) gfPoly { numTotalBytes := data.Len() / 8 if data.Len()%8 != 0 { numTotalBytes++ } result := gfPoly{term: make([]gfElement, numTotalBytes)} i := numTotalBytes - 1 for j := 0; j < data.Len(); j += 8 { result.term[i] = gfElement(data.ByteAt(j)) i-- } return result }