用到一些原生命令行工具: makecab.exe 用于生成 ASCII 0~255 范围内任意字符, fc.exe 用于获取 UTF8 文本字节编码.
全代码超限 8000+字符, 除非取消所有行前缩进, 所以还是分两半发了.
在 65001 代码页下输入中文/英文(随意混合), 输出结果为 svg/htm 和 命令行 以空格和 # 字符构成的字符方阵二维码, 现在手机上的扫描软件完全可适应 # 这种非标准白块. GB 系列编码汉字需要以 "Kanji Mode" 处理(详见 ISO/IEC 18004) 与 UTF8 文本处理有较大差异, 放弃实现.
在 65001 代码页下, 如果 勾选了 传统控制台界面 , 将可能造成 无法用输入法输入中文, 故请忽略代码中关于此问题说明.
代码: 全选
@echo off
REM 更新 20211006_110712, 输出 svg/htm
REM 更新 20190904_231107, 可支持 UTF-8 中文
REM 输入的中文必须为 UTF-8, 不支持 ANSI(GB2312,GBK)编码
REM 一些中文输入法不能在 CMD (65001代码页) 界面输出 UTF-8, 可以在其他文本编辑器中编辑好 UTF-8 文本,
REM 然后粘贴到本程序窗口即可, 如果要在文本中有换行, 请用单个 LF 字符
REM 显示界面必须设置 437 代码页, 如为 win8 ~ win10 系统, 还必须设置勾选传统控制台界面
REM 设置光栅字体 8X8
REM UTF-8 字节码解码原理:
REM 将 UTF-8 文本内容输出到文件, 计算文件大小,
REM 构造完全用 null (\0) 字符构成的等大小文件
REM 用 fc (windows 原生文件比较工具) 的 /b 选项功能获取字节码
cd /d "%~dp0"
if "%~1" neq "" goto :impl
if not exist "%~dp0CHRs" (
echo;genAllChr
2>nul md "%~dp0CHRs" & cd /d "%~dp0CHRs" & call :genAllChr & cd /d "%~dp0"
) else (
echo;"%~dp0CHRs" already exist.
)
setlocal enabledelayedexpansion
chcp 65001
set /p "data_txt=Input data:"
REM set "data_txt=绘画"
>data.txt <nul set /p "=%data_txt%"
start "" "%ComSpec%" /u /c ">data1.txt <nul set /p =%data_txt%"
for %%f in (data.txt) do (
echo;data_len:%%~zf
set "data_len=%%~zf"
)
>0byte.txt cd.
>nul copy /y 0byte.txt same_len.txt
>nul copy /y 0byte.txt rebuild.txt
for /L %%i in (1 1 %data_len%) do (
>nul copy /b same_len.txt + "CHRs\0.chr" same_len.txt
)
for /f "tokens=2" %%b in ('fc /b data.txt same_len.txt ^| findstr ":"') do (
set "data=!data!\x%%b"
REM set /a "dec_num=0x%%b"
REM copy /b rebuild.txt + "CHRs\!dec_num!.chr" rebuild.txt
)
echo;!data!
REM echo;pause_20211005_224539
REM pause
echo;start "%ComSpec%" /c "%~0" !data!
REM echo;pause_20211005_225422
REM pause
start "QRCODE_CMD" "%ComSpec%" /c "%~0" !data!
REM echo;pause_20211005_224551
<nul set /p "=any key to exit..."
>nul pause
exit
:impl
REM chcp 437
set "data=%~1"
REM If you want to rewrite the registry to automatically set the console font size to 8X8 pixels, please un-remark the next line.
REM %1 @goto :initCON
@echo off & mode 200, 200 & rem chcp 437
echo;
echo; QRCODE.CMD
echo;
echo; Author neorobin -- Update @ Oct. 6, 2021
echo; -- Rewritten in CMD Batch @ Nov. 12, 2014
echo;
echo; Author davidshimjs -- QRCode for Javascript library
echo; See http://www.d-project.com/
echo; See http://jeromeetienne.github.com/jquery-qrcode/
echo;
echo; ---------------------------------------------------------------------
echo; QRCode for JavaScript
echo;
echo; Copyright (c) 2009 Kazuhiko Arase
echo;
echo; URL: http://www.d-project.com/
echo;
echo; Licensed under the MIT license:
echo; http://www.opensource.org/licenses/mit-license.php
echo;
echo; The word "QR Code" is registered trademark of
echo; DENSO WAVE INCORPORATED
echo; http://www.denso-wave.com/qrcode/faqpatent-e.html
echo;
echo; ---------------------------------------------------------------------
echo;
REM ************************************************************
REM *
REM * Main Program
REM *
REM ************************************************************
REM If you want to clear some environment variables to speed up running, you can un-remark the next line.
setlocal enabledelayedexpansion
call :initGlobalVars
REM call :quickShow
:main.loop
REM If the data contains Unicode UTF-8 characters, you must add the BOM data header (\xEF\xBB\xBF).
REM set "BOM=\xEF\xBB\xBF"
echo;
REM set /p "data=Input data:"
if "!data!"=="" goto :main.loop
set "errorCorrectLevel="
REM set /p "t=Choose a error correct level (L/M/Q/H):"
set "t=L"
for %%a in (L:1 M:0 Q:3 H:2) do for /f "tokens=1,2 delims=:" %%v in ("%%a") do if /i "%t%"=="%%v" set "errorCorrectLevel=%%w"
if "%errorCorrectLevel%"=="" set "errorCorrectLevel=1"
REM A - Auto, [0..7] - spec, else random
REM set /p "mp=Choose a mask pattern between 0 and 7 :"
set "mp=0"
if /i "!mp!"=="A" (
set "maskPattern="
) else if "!mp!" geq "0" (
if "!mp!" leq "7" (
set /a "maskPattern = !mp:~0,1!"
) else (
set "mp=r"
)
) else (
set "mp=r"
)
if "!mp!"=="r" (
set /a "maskPattern = !random! & 7"
)
call :QRCode.makeCode data errorCorrectLevel maskPattern
REM echo;pause_20211005_224744
<nul set /p "=any key to exit..."
>nul pause
exit
REM pause
goto :main.loop
exit
REM ************************************************************
REM *
REM * Functions
REM *
REM ************************************************************
:QRCode.makeCode data errorCorrectLevel maskPattern
setlocal enabledelayedexpansion
echo; & echo;QRCode.makeCode & echo;
set "data=!%~1!"
set /a "errorCorrectLevel = %~2"
set "maskPattern=!%~3!"
REM chcp 65001
set data
REM chcp 437
set errorCorrectLevel
set maskPattern
set "oQRCodeModel.dataList="
call :_getTypeNumber TypeNumber data errorCorrectLevel
REM If the initial size of the console is too small to display a large size QR Code image,
REM you can un-remark the next line to auto resize the console window.
REM call :autoResizeScr typeNumber 20
set typeNumber
call :QRCodeModel.addData oQRCodeModel.dataList oQRCodeModel.dataCache data
set oQRCodeModel.dataList
call :QRCodeModel.make oQRCodeModel typeNumber errorCorrectLevel maskPattern
call :paint oQRCodeModel.modules oQRCodeModel.moduleCount
endlocal
exit /b
REM end of :QRCode.makeCode
REM ***
:QRCodeModel.make oQRCodeModel typeNumber errorCorrectLevel specifiedMaskPattern
setlocal enabledelayedexpansion
set "oQRCodeModel.dataList=!%~1.dataList!"
set "oQRCodeModel.dataCache=!%~1.dataCache!"
set /a "typeNumber = %~2, errorCorrectLevel = %~3"
set "BestMaskPattern=!%~4!"
if "!BestMaskPattern!"=="" (
call :QRCodeModel.getBestMaskPattern oQRCodeModel typeNumber errorCorrectLevel BestMaskPattern
)
REM title QRCODE.CMD typeNumber: %typeNumber%, errorCorrectLevel: %errorCorrectLevel%, BestMaskPattern: %BestMaskPattern%
call :QRCodeModel.makeImpl oQRCodeModel typeNumber 0 BestMaskPattern errorCorrectLevel
(
endlocal
set "%~1.modules=%oQRCodeModel.modules%"
set "%~1.modules.defined=%oQRCodeModel.modules.defined%"
set "%~1.moduleCount=%oQRCodeModel.moduleCount%"
exit /b
)
REM end of :QRCodeModel.make
REM ***
:QRCodeModel.makeImpl oQRCodeModel typeNumber test maskPattern errorCorrectLevel
setlocal enabledelayedexpansion
set /a "typeNumber = %~2, test = %~3, maskPattern = %~4, errorCorrectLevel = %~5"
set "dataList=!%~1.dataList!"
set "dataCache=!%~1.dataCache!"
set /a "moduleCount = typeNumber * 4 + 17"
set "modules="
set /a "iMax= moduleCount * moduleCount, iByteMax = (iMax >> 3) + ^!^!(iMax & 7), iQuadMax = iByteMax << 1"
for /l %%i in (1 1 %iByteMax%) do set "modules=00!modules!"
set "modules.defined=!modules!"
echo;QRCodeModel.setupPositionProbePattern
call :QRCodeModel.setupPositionProbePattern modules 0 0 moduleCount
call :QRCodeModel.setupPositionProbePattern modules "(moduleCount - 7)" 0 moduleCount
call :QRCodeModel.setupPositionProbePattern modules 0 "(moduleCount - 7)" moduleCount
echo;QRCodeModel.setupPositionAdjustPattern
call :QRCodeModel.setupPositionAdjustPattern modules typeNumber moduleCount
echo;QRCodeModel.setupTimingPattern
call :QRCodeModel.setupTimingPattern modules moduleCount
echo;QRCodeModel.setupTypeInfo
call :QRCodeModel.setupTypeInfo modules test maskPattern errorCorrectLevel moduleCount
if !typeNumber! geq 7 (
echo;QRCodeModel.setupTypeNumber
call :QRCodeModel.setupTypeNumber modules test typeNumber moduleCount
)
if "%dataCache%"=="" (
call :QRCodeModel.createData dataCache typeNumber errorCorrectLevel dataList
)
call :QRCodeModel.mapData modules moduleCount dataCache maskPattern
(
endlocal
set "%~1.modules=%modules%"
set "%~1.modules.defined=%modules.defined%"
set "%~1.moduleCount=%moduleCount%"
exit /b
)
REM end of :QRCodeModel.makeImpl
REM ***
:QRCodeModel.getBestMaskPattern oQRCodeModel typeNumber errorCorrectLevel BestMaskPattern
echo; & echo;QRCodeModel.getBestMaskPattern & echo;
setlocal enabledelayedexpansion
set "oQRCodeModel.dataList=!%~1.dataList!"
set "oQRCodeModel.dataCache=!%~1.dataCache!"
set /a "typeNumber = %~2, errorCorrectLevel = %~3"
set /a "minLostPoint = 1 << IMSB ^ -1, pattern = 0"
for /L %%i in (0 1 7) do (
call :QRCodeModel.makeImpl oQRCodeModel typeNumber 1 %%i errorCorrectLevel
call :QRUtil.getLostPoint oQRCodeModel lostPoint
echo;pattern: %%i, lostPoint: !lostPoint!
if !minLostPoint! gtr !lostPoint! (
set /a "minLostPoint = lostPoint, pattern = %%i"
)
)
(
endlocal
set "%~4=%pattern%"
exit /b
)
REM end of :QRCodeModel.getBestMaskPattern
REM ***
:QRUtil.getLostPoint oQRCodeModel.qrCode lostPoint
echo; & echo;QRCodeModel.getLostPoint & echo;
setlocal enabledelayedexpansion
set "modules=!%~1.modules!"
set /a "moduleCount = %~1.moduleCount, lostPoint = 0, rm = moduleCount - 1, cm = rm, m_2 = rm - 1"
set "LEQ=-1-"
set moduleCount
for /L %%r in (0 1 %rm%) do for /L %%c in (0 1 %cm%) do (
set /a "sameCount = 0, ibs = %%c + %%r * moduleCount, iqs = ibs >> 2"
for %%a in (!iqs!) do (
set /a "dark = 0x!modules:~%%a,1! >> (3 ^^ (ibs & 3)) & 1"
)
for %%L in (-1 0 1) do (
set /a "t = %%r + %%L, t |= moduleCount %LEQ% t"
if !t! geq 0 (
for %%F in (-1 0 1) do (
set /a "t = %%c + %%F, t |= moduleCount %LEQ% t"
if !t! geq 0 if "%%L%%F" neq "00" (
set /a "ibs1 = ibs + %%F + %%L * moduleCount, iqs1 = ibs1 >> 2"
for %%a in (!iqs1!) do (
set /a "sameCount += ^!(dark ^^ (0x!modules:~%%a,1! >> (3 ^^ (ibs1 & 3)) & 1))"
)
)
)
)
)
set /a "lostPoint += (5 - sameCount >> IMSB) & (sameCount - 2)"
)
for /L %%r in (0 1 %m_2%) do for /L %%c in (0 1 %m_2%) do (
set "t=0"
set /a "ibs = %%c + %%r * moduleCount, iqs = ibs >> 2"
for %%a in (!iqs!) do (
set /a "t |= 0x!modules:~%%a,1! >> (3 ^^ (ibs & 3)) & 1"
)
set /a "ibs += 1, iqs = ibs >> 2"
for %%a in (!iqs!) do (
set /a "t |= (0x!modules:~%%a,1! >> (3 ^^ (ibs & 3)) & 1) << 1"
)
set /a "ibs += moduleCount, iqs = ibs >> 2"
for %%a in (!iqs!) do (
set /a "t |= (0x!modules:~%%a,1! >> (3 ^^ (ibs & 3)) & 1) << 2"
)
set /a "ibs -= 1, iqs = ibs >> 2"
for %%a in (!iqs!) do (
set /a "t |= (0x!modules:~%%a,1! >> (3 ^^ (ibs & 3)) & 1) << 3"
)
set /a "lostPoint += (^!t | ^!(t - 0xF)) << IMSB >> IMSB & 3"
)
set /a "m_7 = moduleCount - 7"
for /L %%r in (0 1 %rm%) do for /L %%c in (0 1 %m_7%) do (
set /a "ibs = %%c + %%r * moduleCount, iqs = ibs >> 2, ibs += 6, lenQuad = (ibs >> 2) - iqs + 1"
for /f "tokens=1-2" %%a in ("!iqs! !lenQuad!") do (
set /a "lostPoint += ^!(0x!modules:~%%a,%%b! >> (3 ^^ (ibs & 3)) & 0x7F ^^ 0x5D) << IMSB >> IMSB & 40"
)
)
set /a "m_7 = moduleCount - 7"
for /L %%c in (0 1 %cm%) do for /L %%r in (0 1 %m_7%) do (
set "t=0"
set /a "ibs = %%c + %%r * moduleCount, iqs = ibs >> 2"
for %%a in (!iqs!) do (
set /a "t |= 0x!modules:~%%a,1! >> (3 ^^ (ibs & 3)) & 1"
)
for /L %%d in (1 1 6) do (
set /a "ibs += moduleCount, iqs = ibs >> 2"
for %%a in (!iqs!) do (
set /a "t |= (0x!modules:~%%a,1! >> (3 ^^ (ibs & 3)) & 1) << %%d"
)
)
set /a "lostPoint += ^!(t ^^ 0x5D) << IMSB >> IMSB & 40"
)
set /a "t = moduleCount * moduleCount, iQuadEnd = t / 4 + ^!^!(t %% 4) - 1"
set /a "qStep = WORDSIZE / 4, darkCount = 0"
for /L %%i in (0 %qStep% %iQuadEnd%) do (
set /a "t = 0x!modules:~%%i,%qStep%!"
for /L %%j in (0 1 %IMSB%) do set /a "darkCount += t >> %%j & 1"
)
set /a "lostPoint += (x = 200 * darkCount / (moduleCount * moduleCount) - 100, t = x >> IMSB, (t&-x|~t&x))"
(
endlocal
set "%~2=%lostPoint%"
exit /b
)
REM end of :QRUtil.getLostPoint
REM ***
:_getTypeNumber TypeNumber sText nCorrectLevel
setlocal enabledelayedexpansion
set "sText=!%~2!"
set /a "nCorrectLevel = %~3, j = nCorrectLevel ^ 1"
set "QRCodeLimitLength=17_14_11_7 32_26_20_14 53_42_32_24 78_62_46_34 106_84_60_44 134_106_74_58 154_122_86_64 192_152_108_84 230_180_130_98 271_213_151_119 321_251_177_137 367_287_203_155 425_331_241_177 458_362_258_194 520_412_292_220 586_450_322_250 644_504_364_280 718_560_394_310 792_624_442_338 858_666_482_382 929_711_509_403 1003_779_565_439 1091_857_611_461 1171_911_661_511 1273_997_715_535 1367_1059_751_593 1465_1125_805_625 1528_1190_868_658 1628_1264_908_698 1732_1370_982_742 1840_1452_1030_790 1952_1538_1112_842 2068_1628_1168_898 2188_1722_1228_958 2303_1809_1283_983 2431_1911_1351_1051 2563_1989_1423_1093 2699_2099_1499_1139 2809_2213_1579_1219 2953_2331_1663_1273"
call :dataList.getLength QRCodeLimitLength QRCodeLimitLength.length
set /a "nType = 1"
call :strLen sText length
set "i=0"
:_getTypeNumber.for_i
if %i% geq %QRCodeLimitLength.length% goto :_getTypeNumber.for_i.break
set "nLimit=0"
call :{} QRCodeLimitLength i QRCodeLimitLength[i]
call :[] QRCodeLimitLength[i] j nLimit
if %length% leq %nLimit% (
goto :_getTypeNumber.for_i.break
) else (
set /a "nType += 1"
)
set /a "i += 1"
goto :_getTypeNumber.for_i
:_getTypeNumber.for_i.break
if %nType% gtr %QRCodeLimitLength.length% (
call :throwError "Too long data"
)
(
endlocal
set "%~1=%nType%"
exit /b
)
REM end of :_getTypeNumber
REM ***
:QRRSBlock.RS_BLOCK_TABLE index arrRt
setlocal enabledelayedexpansion
set /a "i = %~1 / 31 + 1, j = %~1 %% 31 + 1"
for /f "tokens=%i% delims=;" %%a in ("1_26_19 1_26_16 1_26_13 1_26_9 1_44_34 1_44_28 1_44_22 1_44_16 1_70_55 1_70_44 2_35_17 2_35_13 1_100_80 2_50_32 2_50_24 4_25_9 1_134_108 2_67_43 2_33_15_2_34_16 2_33_11_2_34_12 2_86_68 4_43_27 4_43_19 4_43_15 2_98_78 4_49_31 2_32_14_4_33_15 4_39_13_1_40_14 2_121_97 2_60_38_2_61_39 4_40_18_2_41_19;4_40_14_2_41_15 2_146_116 3_58_36_2_59_37 4_36_16_4_37_17 4_36_12_4_37_13 2_86_68_2_87_69 4_69_43_1_70_44 6_43_19_2_44_20 6_43_15_2_44_16 4_101_81 1_80_50_4_81_51 4_50_22_4_51_23 3_36_12_8_37_13 2_116_92_2_117_93 6_58_36_2_59_37 4_46_20_6_47_21 7_42_14_4_43_15 4_133_107 8_59_37_1_60_38 8_44_20_4_45_21 12_33_11_4_34_12 3_145_115_1_146_116 4_64_40_5_65_41 11_36_16_5_37_17 11_36_12_5_37_13 5_109_87_1_110_88 5_65_41_5_66_42 5_54_24_7_55_25 11_36_12 5_122_98_1_123_99 7_73_45_3_74_46;15_43_19_2_44_20 3_45_15_13_46_16 1_135_107_5_136_108 10_74_46_1_75_47 1_50_22_15_51_23 2_42_14_17_43_15 5_150_120_1_151_121 9_69_43_4_70_44 17_50_22_1_51_23 2_42_14_19_43_15 3_141_113_4_142_114 3_70_44_11_71_45 17_47_21_4_48_22 9_39_13_16_40_14 3_135_107_5_136_108 3_67_41_13_68_42 15_54_24_5_55_25 15_43_15_10_44_16 4_144_116_4_145_117 17_68_42 17_50_22_6_51_23 19_46_16_6_47_17 2_139_111_7_140_112 17_74_46 7_54_24_16_55_25 34_37_13 4_151_121_5_152_122 4_75_47_14_76_48 11_54_24_14_55_25 16_45_15_14_46_16 6_147_117_4_148_118;6_73_45_14_74_46 11_54_24_16_55_25 30_46_16_2_47_17 8_132_106_4_133_107 8_75_47_13_76_48 7_54_24_22_55_25 22_45_15_13_46_16 10_142_114_2_143_115 19_74_46_4_75_47 28_50_22_6_51_23 33_46_16_4_47_17 8_152_122_4_153_123 22_73_45_3_74_46 8_53_23_26_54_24 12_45_15_28_46_16 3_147_117_10_148_118 3_73_45_23_74_46 4_54_24_31_55_25 11_45_15_31_46_16 7_146_116_7_147_117 21_73_45_7_74_46 1_53_23_37_54_24 19_45_15_26_46_16 5_145_115_10_146_116 19_75_47_10_76_48 15_54_24_25_55_25 23_45_15_25_46_16 13_145_115_3_146_116 2_74_46_29_75_47 42_54_24_1_55_25 23_45_15_28_46_16;17_145_115 10_74_46_23_75_47 10_54_24_35_55_25 19_45_15_35_46_16 17_145_115_1_146_116 14_74_46_21_75_47 29_54_24_19_55_25 11_45_15_46_46_16 13_145_115_6_146_116 14_74_46_23_75_47 44_54_24_7_55_25 59_46_16_1_47_17 12_151_121_7_152_122 12_75_47_26_76_48 39_54_24_14_55_25 22_45_15_41_46_16 6_151_121_14_152_122 6_75_47_34_76_48 46_54_24_10_55_25 2_45_15_64_46_16 17_152_122_4_153_123 29_74_46_14_75_47 49_54_24_10_55_25 24_45_15_46_46_16 4_152_122_18_153_123 13_74_46_32_75_47 48_54_24_14_55_25 42_45_15_32_46_16 20_147_117_4_148_118 40_75_47_7_76_48 43_54_24_22_55_25;10_45_15_67_46_16 19_148_118_6_149_119 18_75_47_31_76_48 34_54_24_34_55_25 20_45_15_61_46_16") do (
for /f "tokens=%j%" %%b in ("%%a") do (
set "_=%%b"
)
)
(
endlocal
set "%~2=%_%"
exit /b
)
REM end of :QRRSBlock.RS_BLOCK_TABLE
REM ***
:QRRSBlock.getRSBlocks typeNumber errorCorrectLevel listRet
setlocal enabledelayedexpansion
set /a "typeNumber = %~1, errorCorrectLevel = %~2"
call :QRRSBlock.getRsBlockTable typeNumber errorCorrectLevel rsBlock
if "%rsBlock%"=="." (
call :throwError "bad rs block @ typeNumber: %typeNumber% /errorCorrectLevel: %errorCorrectLevel%"
)
call :length rsBlock "_" len
set /a "i_m = len / 3 - 1"
set "list="
for /L %%i in (0 1 %i_m%) do (
call :[] rsBlock "(%%i * 3)" count
set /a "count_1 = count - 1"
call :[] rsBlock "(%%i * 3 + 1)" totalCount
call :[] rsBlock "(%%i * 3 + 2)" dataCount
for /L %%j in (0 1 !count_1!) do (
set "list=!list!!totalCount!_!dataCount! "
)
)
(
endlocal
set "%~3=%list:~0,-1%"
exit /b
)
REM end of :QRRSBlock.getRSBlocks
REM ***
:QRRSBlock.getRsBlockTable typeNumber errorCorrectLevel arrRt
setlocal enabledelayedexpansion
set /a "_t = %~2 & ~3"
if %_t%==0 (
set /a "index = ((%~1 - 1) << 2) | (%~2 ^ 1)"
call :QRRSBlock.RS_BLOCK_TABLE index ret
) else (
set "ret=."
)
(
endlocal
set "%~3=%ret%"
exit /b
)
REM end of :QRRSBlock.getRsBlockTable
REM ***
:QRCodeModel.createData bytes typeNumber errorCorrectLevel dataList
setlocal enabledelayedexpansion
set /a "PAD0 = 0xEC, PAD1 = 0x11"
set /a "typeNumber = %~2"
set "dataList=!%~4!"
call :QRRSBlock.getRSBlocks typeNumber errorCorrectLevel rsBlocks
set "buffer.buffer="
set "buffer.length=0"
call :dataList.getLength dataList dataList.length
set /a "im = dataList.length - 1"
for /L %%i in (0 1 %im%) do (
call :{} dataList %%i data
call :QRBitBuffer.put buffer.buffer buffer.length MODE_8BIT_BYTE 4
call :QRUtil.getLengthInBits MODE_8BIT_BYTE typeNumber len
call :strLen data data.getLength
set /a "data.getLength >>= 1"
call :QRBitBuffer.put buffer.buffer buffer.length data.getLength len
call :QR8bitByte.write buffer.buffer buffer.length data
)
set "totalDataCount=0"
for %%a in (%rsBlocks%) do (
set "t=%%a"
set /a "totalDataCount += !t:_=&0|!"
)
set /a "totalDataCount_m8 = totalDataCount << 3"
if %buffer.length% gtr %totalDataCount_m8% (
call :throwError "code length overflow. [%buffer.length% gtr %totalDataCount_m8%]"
)
set /a "t = buffer.length + 4"
if %t% leq %totalDataCount_m8% (
call :QRBitBuffer.put buffer.buffer buffer.length 0 4
)
set /a "im = buffer.length & 7 ^ 7"
if %im% neq 7 (
for /L %%i in (0 1 %im%) do call :QRBitBuffer.putBit buffer.buffer buffer.length 0
)
:QRCodeModel.createData.while_true
if %buffer.length% geq %totalDataCount_m8% goto :QRCodeModel.createData.break
call :QRBitBuffer.put buffer.buffer buffer.length PAD0 8
if %buffer.length% geq %totalDataCount_m8% goto :QRCodeModel.createData.break
call :QRBitBuffer.put buffer.buffer buffer.length PAD1 8
goto :QRCodeModel.createData.while_true
:QRCodeModel.createData.break
call :QRCodeModel.createBytes bytes buffer.buffer rsBlocks
(
endlocal
set "%~1=%bytes%"
exit /b
)
REM end of :QRCodeModel.createData
REM ***
:QRCodeModel.mapData modules moduleCount dataCache maskPattern
setlocal enabledelayedexpansion
set "m=!%~1!"
set "m.def=!%~1.defined!"
set "data=!%~3!"
set /a "moduleCount = %~2, moduleCount_1 = moduleCount - 1, "^
"inc = -1, row = moduleCount_1, bitIndex = 7, iQuad = 0, maskPattern = %~4"
set "LEQ=-1-"
call :strLen data data.quadLen
set "$0=~(row+rnk)&1"
set "$1=~row&1"
set "$2=^!(rnk %% 3)"
set "$3=^!((row+rnk) %% 3)"
set "$4=~((row>>1)+rnk/3)&1"
set "$5=(t=row*rnk,^!(t&1)&^!(t %% 3))"
set "$6=(t=row*rnk,~((t&1)+t %% 3)&1)"
set "$7=~(row*rnk %% 3+((row+rnk)&1))&1"
set /a "col = moduleCount_1"
:QRCodeModel.mapData.for_col
<nul set /p "=%BS%%BS%%BS%%BS%%BS%%BS%%BS%%BS%%BS%%BS%%BS%%BS%%BS%%BS%%BS%%BS%%BS%COLUMN: %col%/%moduleCount_1% "
if %col% leq 0 goto :QRCodeModel.mapData.for_col.end
set /a "t = ^!(col ^^ 6) << IMSB >> IMSB, col = t & 5 | ~t & col"
:QRCodeModel.mapData.while_true
for %%c in (0 1) do (
set /a "rnk = col - %%c, ibs = rnk + row * moduleCount, lenL = ibs >> 2, bit = 1 << (3 ^ (ibs & 3))"
for %%a in (!lenL!) do (
set /a "quad.def = 0x!m.def:~%%a,1! & bit"
)
if !quad.def!==0 (
set "dark=0"
if !iQuad! lss %data.quadLen% (
for %%i in (!iQuad!) do (
set /a "dark = (0x!data:~%%i,2! >> bitIndex) & 1"
)
)
for %%i in (%maskPattern%) do set /a "mask = !$%%i!, dark ^^= mask"
set /a "SBB = dark << IMSB >> IMSB, ind = lenL + 1, lenR = iQuadMax - ind"
for %%a in (!lenL!) do (
set /a "quad = 0x!m:~%%a,1!, quad = SBB & (bit | quad) | ~SBB & (~bit & quad), "^
"quad.def = 0x!m.def:~%%a,1! | bit"
)
for /f "tokens=1-5" %%A in ("!lenL! !ind! !lenR! #!quad! #!quad.def!") do (
set "m=!m:~0,%%A!!%%D!!m:~%%B,%%C!"
set "m.def=!m.def:~0,%%A!!%%E!!m.def:~%%B,%%C!"
)
set /a "bitIndex -= 1, t = bitIndex >> IMSB, bitIndex = t & 7 | ~t & bitIndex, iQuad += t & 2"
)
)
set /a "row += inc, t = row | moduleCount %LEQ% row"
if %t% lss 0 (
set /a "row -= inc, inc = -inc"
goto :QRCodeModel.mapData.while_true.break
)
goto :QRCodeModel.mapData.while_true
:QRCodeModel.mapData.while_true.break
set /a "col -= 2"
goto :QRCodeModel.mapData.for_col
:QRCodeModel.mapData.for_col.end
(
endlocal
set "%~1=%m%"
set "%~1.defined=%m.def%"
exit /b
)
REM end of :QRCodeModel.mapData
REM ***
:dataList.getLength dataList dataList.length
setlocal enabledelayedexpansion
if "!%~1!"=="." (
set "length=0"
) else (
set "t=!%~1!"
set "t1=!t: =!"
call :strLen t len
call :strLen t1 len1
set /a "length = len - len1 + 1"
)
(
endlocal
set "%~2=%length%"
exit /b
)
REM end of :dataList.getLength
REM ***
:QR8bitByte.write QRBitBuffer.buffer QRBitBuffer.length QR8bitByte.parsedData
setlocal enabledelayedexpansion
set "buf=!%~1!"
set "buf.len=!%~2!"
set "pd=!%~3!"
call :strLen pd pd.len
set /a "im = pd.len - 2"
for /L %%i in (0 2 %im%) do (
set /a "num = 0x!pd:~%%i,2!"
call :QRBitBuffer.put buf buf.len num 8
)
(
endlocal
set "%~1=%buf%"
set "%~2=%buf.len%"
exit /b
)
REM end of :QR8bitByte.write
REM ***
:QRCodeModel.createBytes bytes QRBitBuffer.buffer rsBlocks
setlocal enabledelayedexpansion
set /a "offset = 0, maxDcCount = 0, maxEcCount = 0"
set "rsbs=!%~3!"
call :dataList.getLength rsbs rMax
set /a "rMax -= 1"
set "dcdata="
set "ecdata="
for /L %%r in (0 1 %rMax%) do (
call :{} rsbs %%r rsbs[r]
call :[] rsbs[r] 1 dcCount
call :[] rsbs[r] 0 rsbs[r].tc
set /a "ecCount = rsbs[r].tc - dcCount, dcC_1 = dcCount - 1,"^
"t = maxDcCount - dcCount >> IMSB, maxDcCount = t & dcCount | ~t & maxDcCount,"^
"t = maxEcCount - ecCount >> IMSB, maxEcCount = t & ecCount | ~t & maxEcCount"
for /L %%i in (0 1 !dcC_1!) do (
set /a "_i = (%%i + offset) << 1"
for %%a in (!_i!) do set "dcdata=!dcdata!!%~2:~%%a,2!"
)
set "dcdata=!dcdata! "
set /a "offset += dcCount"
call :QRUtil.getErrorCorrectPolynomial ecCount rsPoly
call :strLen rsPoly rsPoly.getLength
set /a "shift = rsPoly.getLength - 2 >> 1"
call :{} dcdata %%r dcdata[r]
call :QRPolynomial.QRPolynomial rawPoly dcdata[r] shift
call :QRPolynomial.mod rawPoly rsPoly modPoly
call :strLen modPoly modPoly.getLength
set /a "ecdata[r].length = rsPoly.getLength - 2"
set /a "j = modPoly.getLength - ecdata[r].length"
set /a "is = j, im = ecdata[r].length - 2 + j"
for /L %%i in (!is! 2 !im!) do (
if %%i geq 0 (
set "ecdata=!ecdata!!modPoly:~%%i,2!"
) else (
set "ecdata=!ecdata!00"
)
)
set "ecdata=!ecdata! "
)
set "ecdata=%ecdata:~0,-1%"
set "dcdata=%dcdata:~0,-1%"
set "totalCodeCount=0"
for %%a in (%rsbs%) do (
set "t=%%a"
set /a "totalCodeCount += !t:_=|0&!"
)
set "data="
set /a "im = maxDcCount - 1 << 1"
for /L %%i in (0 2 %im%) do (
for /L %%r in (0 1 %rMax%) do (
call :{} dcdata %%r dcdata[r]
call :strlen dcdata[r] dcdata[r].length
if %%i lss !dcdata[r].length! (
set "data=!data!!dcdata[r]:~%%i,2!"
)
)
)
set /a "im = maxEcCount - 1 << 1"
for /L %%i in (0 2 %im%) do (
for /L %%r in (0 1 %rMax%) do (
call :{} ecdata %%r ecdata[r]
call :strlen ecdata[r] ecdata[r].length
if %%i lss !ecdata[r].length! (
set "data=!data!!ecdata[r]:~%%i,2!"
)
)
)
set /a "im = totalCodeCount - 2"
call :strlen data data.len
for /L %%i in (%data.len% 2 %im%) do (
set "data=!data!00"
)
(
endlocal
set "%~1=%data%"
exit /b
)
REM end of :QRCodeModel.createBytes
REM ***
:QRUtil.getErrorCorrectPolynomial errorCorrectLength arrRet
setlocal enabledelayedexpansion
set "a=01"
set /a "im = %~1 - 1 << 1"
for /L %%i in (0 2 %im%) do (
set "num=01!EXP_TABLE:~%%i,2!"
call :QRPolynomial.QRPolynomial poly num 0
call :QRPolynomial.multiply a poly a
)
(
endlocal
set "%~2=%a%"
exit /b
)
REM end of :QRUtil.getErrorCorrectPolynomial
REM ***
:QRPolynomial.mod this e mod
setlocal enabledelayedexpansion
set "this=!%~1!"
set "e=!%~2!"
:QRPolynomial.mod.loop
call :strLen this this.getLength
call :strLen e e.getLength
if %this.getLength% lss %e.getLength% (
goto :QRPolynomial.mod.end
)
set /a "a = 0x!this:~0,2! << 1, b = 0x!e:~0,2! << 1"
for /f "tokens=1-2" %%a in ("!a! !b!") do (
set /a "ratio = 0x!LOG_TABLE:~%%a,2! - 0x!LOG_TABLE:~%%b,2!"
)
set "num=%this%"
set /a "im = e.getLength - 2"
for /L %%i in (0 2 %im%) do (
set /a "e[i] = 0x!e:~%%i,2! << 1"
for %%a in (!e[i]!) do (
set /a "P = 0x!LOG_TABLE:~%%a,2! + ratio, t=(P^^P-256)>>IMSB, r=P %% 255, c = ^!r <<IMSB>>IMSB, P = (t & P | ~t & r + ((P>>IMSB ^^ c) & 255)) << 1"
)
set /a "ind = %%i + 2, lenR = this.getLength - ind"
for %%A in (!P!) do (
set /a "n = 0x!num:~%%i,2! ^^ 0x!EXP_TABLE:~%%A,2!"
)
set /a "H4 = n >> 4, L4 = n & 0xF"
for /f "tokens=1-4" %%V in ("!ind! !lenR! #!H4! #!L4!") do set "num=!num:~0,%%i!!%%X!!%%Y!!num:~%%V,%%W!"
)
call :QRPolynomial.QRPolynomial this num 0
goto :QRPolynomial.mod.loop
:QRPolynomial.mod.end
(
endlocal
set "%~3=%this%"
exit /b
)
REM end of :QRPolynomial.mod
REM ***
:QRPolynomial.multiply this e multi
setlocal enabledelayedexpansion
set "this=!%~1!"
set "e=!%~2!"
call :strLen this this.getLength
call :strLen e e.getLength
set /a "len = this.getLength + e.getLength - 2, im = this.getLength - 2, jm = e.getLength - 2"
set "num="
for /L %%i in (1 1 %len%) do set "num=!num!0"
for /L %%i in (0 2 %im%) do (
for /L %%j in (0 2 %jm%) do (
set /a "a = 0x!this:~%%i,2! << 1, b = 0x!e:~%%j,2! << 1"
for /f "tokens=1-2" %%a in ("!a! !b!") do (
set /a "P = 0x!LOG_TABLE:~%%a,2! + 0x!LOG_TABLE:~%%b,2!"
)
set /a "t=(P^^P-256)>>IMSB, r=P %% 255, c = ^!r <<IMSB>>IMSB, P = (t & P | ~t & r + ((P>>IMSB ^^ c) & 255)) << 1"
set /a "lenL = %%i + %%j, ind = lenL + 2, lenR = len - ind"
for /f "tokens=1-2" %%A in ("!lenL! !P!") do (
set /a "n = 0x!num:~%%A,2! ^^ 0x!EXP_TABLE:~%%B,2!"
)
set /a "H4 = n >> 4, L4 = n & 0xF"
for /f "tokens=1-5" %%U in ("!lenL! !ind! !lenR! #!H4! #!L4!") do set "num=!num:~0,%%U!!%%X!!%%Y!!num:~%%V,%%W!"
)
)
call :QRPolynomial.QRPolynomial T num 0
(
endlocal
set "%~3=%T%"
exit /b
)
REM end of :QRPolynomial.multiply
REM ***
:QRPolynomial.QRPolynomial this.num num shift
setlocal enabledelayedexpansion
if "!%~2!"=="" (
call :throwError "@QRPolynomial.QRPolynomial num:[%~2] / shift=[%~3]"
)
set "num=!%~2!"
set "offset=0"
:QRPolynomial.QRPolynomial.L1
set /a "offs = offset << 1"
for %%i in (%offs%) do set "num{offset}=!num:~%%i,2!"
call :strLen num num.length
set /a "num.length >>= 1"
set /a "t = (offset - num.length) & (^! 0x%num{offset}% << IMSB)"
if %t% lss 0 (
set /a "offset += 1"
goto :QRPolynomial.QRPolynomial.L1
)
set /a "im = num.length - offset - 1"
for /L %%i in (0 1 %im%) do (
set /a "i_offset = %%i + offset << 1"
for %%a in (!i_offset!) do set "this_num=!this_num!!num:~%%a,2!"
)
set /a "shift = %~3"
for /L %%i in (1 1 %shift%) do (
set "this_num=!this_num!00"
)
(
endlocal
set "%~1=%this_num%"
exit /b
)
REM end of :QRPolynomial.QRPolynomial
REM ***
:QRCodeModel.setupTypeNumber modules test typeNumber moduleCount
setlocal enabledelayedexpansion
set "t=!%~1!"
set "t.def=!%~1.defined!"
set /a "typeNumber = %~3"
call :QRUtil.getBCHTypeNumber bits typeNumber
for /L %%i in (0 1 17) do (
set /a "bit = ^!%~2 & ((bits >> %%i) & 1)"
set /a "SBB = bit << IMSB >> IMSB, "^
"ibs = (%%i %% 3 + %~4 - 11) + (%%i / 3) * %~4, lenL = ibs >> 2, ind = lenL + 1, lenR = iQuadMax - ind, bit = 1 << (3 ^ (ibs & 3))"
for %%a in (!lenL!) do (
set /a "quad = 0x!t:~%%a,1!, quad = SBB & (bit | quad) | ~SBB & (~bit & quad), "^
"quad.def = 0x!t.def:~%%a,1! | bit"
)
for /f "tokens=1-5" %%A in ("!lenL! !ind! !lenR! #!quad! #!quad.def!") do (
set "t=!t:~0,%%A!!%%D!!t:~%%B,%%C!"
set "t.def=!t.def:~0,%%A!!%%E!!t.def:~%%B,%%C!"
)
)
for /L %%i in (0 1 17) do (
set /a "bit = ^!%~2 & ((bits >> %%i) & 1)"
set /a "SBB = bit << IMSB >> IMSB, "^
"ibs = (%%i / 3) + (%%i %% 3 + %~4 - 11) * %~4, lenL = ibs >> 2, ind = lenL + 1, lenR = iQuadMax - ind, bit = 1 << (3 ^ (ibs & 3))"
for %%a in (!lenL!) do (
set /a "quad = 0x!t:~%%a,1!, quad = SBB & (bit | quad) | ~SBB & (~bit & quad), "^
"quad.def = 0x!t.def:~%%a,1! | bit"
)
for /f "tokens=1-5" %%A in ("!lenL! !ind! !lenR! #!quad! #!quad.def!") do (
set "t=!t:~0,%%A!!%%D!!t:~%%B,%%C!"
set "t.def=!t.def:~0,%%A!!%%E!!t.def:~%%B,%%C!"
)
)
(
endlocal
set "%~1=%t%"
set "%~1.defined=%t.def%"
exit /b
)
REM end of :QRCodeModel.setupTypeNumber
REM ***
:QRCodeModel.setupTypeInfo modules test maskPattern errorCorrectLevel moduleCount
setlocal enabledelayedexpansion
set "t=!%~1!"
set "t.def=!%~1.defined!"
set /a "data = %~4 << 3 | %~3"
call :QRUtil.getBCHTypeInfo bits data
for /L %%i in (0 1 14) do (
if %%i lss 6 (
set "r=%%i"
) else if %%i lss 8 (
set /a "r = %%i + 1"
) else (
set /a "r = %~5 - 15 + %%i"
)
set /a "bit = ^!%~2 & ((bits >> %%i) & 1)"
set /a "SBB = bit << IMSB >> IMSB, "^
"ibs = 8 + r * %~5, lenL = ibs >> 2, ind = lenL + 1, lenR = iQuadMax - ind, bit = 1 << (3 ^ (ibs & 3))"
for %%a in (!lenL!) do (
set /a "quad = 0x!t:~%%a,1!, quad = SBB & (bit | quad) | ~SBB & (~bit & quad), "^
"quad.def = 0x!t.def:~%%a,1! | bit"
)
for /f "tokens=1-5" %%A in ("!lenL! !ind! !lenR! #!quad! #!quad.def!") do (
set "t=!t:~0,%%A!!%%D!!t:~%%B,%%C!"
set "t.def=!t.def:~0,%%A!!%%E!!t.def:~%%B,%%C!"
)
)
for /L %%i in (0 1 14) do (
if %%i lss 8 (
set /a "c = %~5 - %%i - 1"
) else if %%i lss 9 (
set /a "c = 15 - %%i"
) else (
set /a "c = 14 - %%i"
)
set /a "bit = ^!%~2 & ((bits >> %%i) & 1), mod = bit"
set /a "SBB = bit << IMSB >> IMSB, "^
"ibs = c + 8 * %~5, lenL = ibs >> 2, ind = lenL + 1, lenR = iQuadMax - ind, bit = 1 << (3 ^ (ibs & 3))"
for %%a in (!lenL!) do (
set /a "quad = 0x!t:~%%a,1!, quad = SBB & (bit | quad) | ~SBB & (~bit & quad), "^
"quad.def = 0x!t.def:~%%a,1! | bit"
)
for /f "tokens=1-5" %%A in ("!lenL! !ind! !lenR! #!quad! #!quad.def!") do (
set "t=!t:~0,%%A!!%%D!!t:~%%B,%%C!"
set "t.def=!t.def:~0,%%A!!%%E!!t.def:~%%B,%%C!"
)
)
set /a "bit = mod"
set /a "SBB = bit << IMSB >> IMSB, "^
"ibs = 8 + (%~5 - 8) * %~5, lenL = ibs >> 2, ind = lenL + 1, lenR = iQuadMax - ind, bit = 1 << (3 ^ (ibs & 3))"
for %%a in (!lenL!) do (
set /a "quad = 0x!t:~%%a,1!, quad = SBB & (bit | quad) | ~SBB & (~bit & quad), "^
"quad.def = 0x!t.def:~%%a,1! | bit"
)
for /f "tokens=1-5" %%A in ("!lenL! !ind! !lenR! #!quad! #!quad.def!") do (
set "t=!t:~0,%%A!!%%D!!t:~%%B,%%C!"
set "t.def=!t.def:~0,%%A!!%%E!!t.def:~%%B,%%C!"
)
(
endlocal
set "%~1=%t%"
set "%~1.defined=%t.def%"
exit /b
)
REM end of :QRCodeModel.setupTypeInfo
REM ***
:QRUtil.getBCHTypeInfo BCHTypeInfo data
setlocal enabledelayedexpansion
set /a "d = %~2 << 10"
:QRUtil.getBCHTypeInfo.L1
call :QRUtil.getBCHDigit d.digit d
set /a "_d = d.digit - G15.DGT"
if !_d! geq 0 (
set /a "d ^= G15 << _d"
goto :QRUtil.getBCHTypeInfo.L1
)
set /a "_ = (%~2 << 10 | d) ^ G15_MASK"
(
endlocal
set "%~1=%_%"
exit /b
)
REM end of :QRUtil.getBCHTypeInfo
REM ***
:QRUtil.getBCHTypeNumber BCHTypeNumber data
setlocal enabledelayedexpansion
set /a "d = %~2 << 12"
:QRUtil.getBCHTypeNumber.L1
call :QRUtil.getBCHDigit d.digit d
set /a "_d = d.digit - G18.DGT"
if !_d! geq 0 (
set /a "d ^= G18 << _d"
goto :QRUtil.getBCHTypeNumber.L1
)
set /a "_ = %~2 << 12 | d"
(
endlocal
set "%~1=%_%"
exit /b
)
REM end of :QRUtil.getBCHTypeNumber
REM ***
:QRUtil.getBCHDigit digit data
setlocal enabledelayedexpansion
set /a "t = %~2"
if %t% lss 0 (
set "_=%WORDSIZE%"
) else (
set /a "t <<= 1"
set "_=0"
for %%i in (16 8 4 2 1) do (
set /a "_i = ~-^!(t >> %%i) & %%i, _ |= _i, t >>= _i"
)
)
(
endlocal
set "%~1=%_%"
exit /b
)
REM end of :QRUtil.getBCHDigit
REM ***
:QRCodeModel.setupPositionAdjustPattern modules typeNumber moduleCount
setlocal enabledelayedexpansion
call :QRUtil.PATTERN_POSITION_TABLE "(%~2 - 1)" pos
call :length pos "_" pos.length
set "t=!%~1!"
set "t.def=!%~1.defined!"
set /a "L_1 = pos.length - 1"
for /L %%i in (0 1 %L_1%) do (
for /L %%j in (0 1 %L_1%) do (
call :[] pos %%i row
call :[] pos %%j col
set /a "ibs = col + row * %~3, iqs = ibs >> 2, bit = 1 << (3 ^ (ibs & 3))"
for %%a in (!iqs!) do (
set /a "quad.def = 0x!t.def:~%%a,1! & bit"
)
if !quad.def!==0 (
for /L %%r in (-2 1 2) do (
for /L %%c in (-2 1 2) do (
set /a "bit = ^!(%%r & 3 ^^ 2) | ^!(%%c & 3 ^^ 2) | ^!(%%r | %%c), SBB = bit << IMSB >> IMSB"
set /a "ibs = col + %%c + (row + %%r) * %~3, lenL = ibs >> 2, ind = lenL + 1, lenR = iQuadMax - ind, bit = 1 << (3 ^ (ibs & 3))"
for %%a in (!lenL!) do (
set /a "quad = 0x!t:~%%a,1!, quad = SBB & (bit | quad) | ~SBB & (~bit & quad), "^
"quad.def = 0x!t.def:~%%a,1! | bit"
)
for /f "tokens=1-5" %%A in ("!lenL! !ind! !lenR! #!quad! #!quad.def!") do (
set "t=!t:~0,%%A!!%%D!!t:~%%B,%%C!"
set "t.def=!t.def:~0,%%A!!%%E!!t.def:~%%B,%%C!"
)
)
)
)
)
)
(
endlocal
set "%~1=%t%"
set "%~1.defined=%t.def%"
exit /b
)
REM end of :QRCodeModel.setupPositionAdjustPattern