1
hao
2025-03-27 e610e1c17f62b423a717fadaaa7b139d02857793
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
import Barcode from "../Barcode.js";
import { SHIFT, SET_A, SET_B, MODULO, STOP, FNC1, SET_BY_CODE, SWAP, BARS } from './constants';
 
// This is the master class,
// it does require the start code to be included in the string
class CODE128 extends Barcode {
    constructor(data, options) {
        super(data.substring(1), options);
 
        // Get array of ascii codes from data
        this.bytes = data.split('')
            .map(char => char.charCodeAt(0));
    }
 
    valid() {
        // ASCII value ranges 0-127, 200-211
        return /^[\x00-\x7F\xC8-\xD3]+$/.test(this.data);
    }
 
    // The public encoding function
    encode() {
        const bytes = this.bytes;
        // Remove the start code from the bytes and set its index
        const startIndex = bytes.shift() - 105;
        // Get start set by index
        const startSet = SET_BY_CODE[startIndex];
 
        if (startSet === undefined) {
            throw new RangeError('The encoding does not start with a start character.');
        }
 
        if (this.shouldEncodeAsEan128() === true) {
            bytes.unshift(FNC1);
        }
 
        // Start encode with the right type
        const encodingResult = CODE128.next(bytes, 1, startSet);
 
        return {
            text:
                this.text === this.data
                    ? this.text.replace(/[^\x20-\x7E]/g, '')
                    : this.text,
            data:
                // Add the start bits
                CODE128.getBar(startIndex) +
                // Add the encoded bits
                encodingResult.result +
                // Add the checksum
                CODE128.getBar((encodingResult.checksum + startIndex) % MODULO) +
                // Add the end bits
                CODE128.getBar(STOP)
        };
    }
 
    // GS1-128/EAN-128
    shouldEncodeAsEan128() {
        let isEAN128 = this.options.ean128 || false;
        if (typeof isEAN128 === 'string') {
            isEAN128 = isEAN128.toLowerCase() === 'true';
        }
        return isEAN128;
    }
 
    // Get a bar symbol by index
    static getBar(index) {
        return BARS[index] ? BARS[index].toString() : '';
    }
 
    // Correct an index by a set and shift it from the bytes array
    static correctIndex(bytes, set) {
        if (set === SET_A) {
            const charCode = bytes.shift();
            return charCode < 32 ? charCode + 64 : charCode - 32;
        } else if (set === SET_B) {
            return bytes.shift() - 32;
        } else {
            return (bytes.shift() - 48) * 10 + bytes.shift() - 48;
        }
    }
 
    static next(bytes, pos, set) {
        if (!bytes.length) {
            return { result: '', checksum: 0 };
        }
 
        let nextCode, index;
 
        // Special characters
        if (bytes[0] >= 200){
            index = bytes.shift() - 105;
            const nextSet = SWAP[index];
 
            // Swap to other set
            if (nextSet !== undefined) {
                nextCode = CODE128.next(bytes, pos + 1, nextSet);
            }
            // Continue on current set but encode a special character
            else {
                // Shift
                if ((set === SET_A || set === SET_B) && index === SHIFT) {
                    // Convert the next character so that is encoded correctly
                    bytes[0] = (set === SET_A)
                        ? bytes[0] > 95 ? bytes[0] - 96 : bytes[0]
                        : bytes[0] < 32 ? bytes[0] + 96 : bytes[0];
                }
                nextCode = CODE128.next(bytes, pos + 1, set);
            }
        }
        // Continue encoding
        else {
            index = CODE128.correctIndex(bytes, set);
            nextCode = CODE128.next(bytes, pos + 1, set);
        }
 
        // Get the correct binary encoding and calculate the weight
        const enc = CODE128.getBar(index);
        const weight = index * pos;
 
        return {
            result: enc + nextCode.result,
            checksum: weight + nextCode.checksum
        };
    }
}
 
export default CODE128;