// pwuniapp/common/barcode.js // 轻量级原生 Code128 条形码编码与图形数据生成器 (零第三方依赖,跨端兼容小程序与H5) const CODE128_PATTERNS = [ '212222', '222122', '222221', '121223', '121322', '131222', '122213', '122312', '132212', '221213', // 0-9 '221312', '231212', '112232', '122132', '122231', '113222', '123122', '123221', '223211', '221132', // 10-19 '221231', '213212', '223112', '312131', '311222', '321122', '321221', '312212', '322112', '322211', // 20-29 '212123', '212321', '232121', '111323', '131123', '131321', '112313', '132113', '132311', '211313', // 30-39 '231113', '231311', '112133', '112331', '132131', '113123', '113321', '133121', '313121', '211331', // 40-49 '231131', '213113', '213311', '213131', '311123', '311321', '331121', '312113', '312311', '332111', // 50-59 '314111', '221411', '431111', '111224', '111422', '121124', '121421', '141122', '141221', '112214', // 60-69 '112412', '122114', '122411', '142112', '142211', '241211', '221114', '413111', '241112', '134111', // 70-79 '111242', '121142', '121241', '114212', '124112', '124211', '411212', '421112', '421211', '212141', // 80-89 '214121', '412121', '111143', '111341', '131141', '114113', '114311', '411113', '411311', '113141', // 90-99 '114131', '311141', '411131', '211412', '211214', '211232', '2331112' // 100-106 ]; // Start B 对应 index 104 const START_B_INDEX = 104; // Stop 对应 index 106 const STOP_INDEX = 106; /** * 将字符串编码为 Code128B 的条块分布 * @param {string} text 要编码的文本字符串 (ASCII 32 - 126) * @returns {Array<{ isBar: boolean, width: number }>} 条块序列 */ export function encodeCode128B(text) { if (!text) text = '0000'; const codes = [START_B_INDEX]; let checkSum = START_B_INDEX; for (let i = 0; i < text.length; i++) { const charCode = text.charCodeAt(i); // Code 128B 映射: ASCII 32~127 对应 code 0~95 let val = charCode - 32; if (val < 0 || val > 95) val = 0; // 越界字符转为空格 codes.push(val); checkSum += val * (i + 1); } const checkVal = checkSum % 103; codes.push(checkVal); codes.push(STOP_INDEX); // 转换为高精度条空阵列 (Bar and Space array) const segments = []; codes.forEach((codeIndex) => { const pattern = CODE128_PATTERNS[codeIndex]; if (!pattern) return; for (let p = 0; p < pattern.length; p++) { const width = parseInt(pattern[p], 10); const isBar = p % 2 === 0; segments.push({ isBar, width }); } }); return segments; } /** * 转换为 0/1 位图序列 (用于像素级精确渲染) * @param {string} text * @returns {string} 由 '1' 和 '0' 组成的二进制序列 */ export function getBarcodeBits(text) { const segments = encodeCode128B(text); let bits = ''; segments.forEach((seg) => { bits += (seg.isBar ? '1' : '0').repeat(seg.width); }); return bits; }