合肥建網(wǎng)站公司騰訊與中國聯(lián)通
Code 11 是一種高密度的數(shù)字條形碼,主要用于標識電信設備和電子元件。它的名稱來源于其能夠編碼 11 種字符:數(shù)字 0-9 和連接符 -。Code 11 是一種雙向可讀的條形碼,支持校驗位以提高數(shù)據(jù)準確性。
在使用BARCODE_CODE11碼制生成code 11碼時可指定其是否校驗。默認是以兩位校驗碼的設置生成。文檔中的描述為:
Two modulo-11 check digits are added by default. To add just one check digit, set --vers=1 (API option_2 = 1). To add no check digits, set --vers=2 (API option_2 = 2).
故而如果我們需要更改其校驗規(guī)則只需在生成時更改option_2參數(shù)的值即可。
生成代碼如下:
struct zint_symbol* symbol;
symbol = ZBarcode_Create();
symbol->symbology = BARCODE_CODE11; //碼制
symbol->input_mode = DATA_MODE; //數(shù)據(jù)編碼格式
symbol->option_2 = 1; //默認添加倆校驗位、1 添加一個校驗位、2 不添加校驗位std::string strContent = "123456";
CRect rcCode(0,0,200,50);
int nRet = ZBarcode_Encode_and_Buffer_Vector(symbol, (unsigned char*)strContent.c_str(), strContent.size(), 0);
if (nRet == 0)
{//successZBarcode_Print(symbol, 0);std::vector<CRect> vecBlackRect;if (symbol->vector){struct zint_vector_rect* rect = symbol->vector->rectangles;while (rect){CRect rcTmp;rcTmp.left = rect->x;rcTmp.top = rect->y;rcTmp.right = rcTmp.left + rect->width;rcTmp.bottom = rcTmp.top + rect->height;vecBlackRect.push_back(rcTmp);rect = rect->next; } }double nDrawUint = (double)rcCode.Width() / symbol->width;double nUint = (double)symbol->bitmap_width / symbol->width;std::vector<CRect> vecDrawBlack; //繪制條碼條的真實區(qū)域for (int i = 0; i < vecBlackRect.size(); i++){CRect rcTmp(vecBlackRect[i]);rcTmp.left = rcTmp.left / nUint * nDrawUint;rcTmp.right = rcTmp.right / nUint * nDrawUint;rcTmp.bottom = rcTmp.top + rcCode.Height();vecDrawBlack.push_back(rcTmp); }//繪制條碼//可選擇是否繪制條碼背景色{COLORREF clrBkgnd = GETCOLOR(L"RGB(255,255,255)");CAutoRefPtr<IBrush> brush, oldbrush;pRT->CreateSolidColorBrush(clrBkgnd, &brush);pRT->SelectObject(brush, (IRenderObj**)&oldbrush);pRT->FillRectangle(&rcCode);pRT->SelectObject(oldbrush, NULL); }CAutoRefPtr<IPath> path;GETRENDERFACTORY->CreatePath(&path);for (int i = 0; i < vecDrawBlack.size(); i++){CRect rcBlack;rcBlack.left += vecDrawBlack[i].left + rcCode.left;rcBlack.top += vecDrawBlack[i].top + rcCode.top;rcBlack.right = rcBlack.left + vecDrawBlack[i].Width();rcBlack.bottom = rcBlack.top + vecDrawBlack[i].Height();path->addRect(rcBlack); }COLORREF clrFrgnd = GETCOLOR(L"RGB(0,0,0)"); //可自定義條碼前景色CAutoRefPtr<IBrush> brush, oldbrush;pRT->CreateSolidColorBrush(clrFrgnd, &brush);pRT->SelectObject(brush, (IRenderObj**)&oldbrush);pRT->FillPath(path);pRT->SelectObject(oldbrush, NULL);//繪制文本(文本繪制可以選擇繪制在底部還是頂部,自行計算文本位置然后進行繪制)SIZE szContent;pRT->MeasureText(m_sstrContent, m_sstrContent.GetLength(), &szContent); //文本整體的長度CRect rcText(rcCode);rcText.top = rcCode.bottom;rcText.bottom = rcText.top + szContent.cy;pRT->DrawText(m_sstrContent, -1, (LPRECT)rcText, DT_CENTER | DT_VCENTER | DT_SINGLELINE | DT_NOPREFIX);
}
else
{//failed//可查看errtxt值查看失敗描述
}
ZBarcode_Delete(symbol);
在繪制文本時根據(jù)如果需要將校驗碼繪制出來則將校驗碼追加在原始數(shù)據(jù)后進行繪制。
校驗碼計算規(guī)則:
1位校驗碼計算:
- 分配權重:從右到左(從最后一位字符開始),為每個字符分配一個權重,權重從 1 開始遞增。
- 計算加權和:將每個字符的值乘以其權重,然后求和。字符 - 的值為 10。
- 計算校驗碼:將加權和除以 11,取余數(shù)作為校驗碼。如果余數(shù)為 10,則校驗碼為 -。
- 附加校驗碼:將校驗碼附加到條碼數(shù)據(jù)的末尾。
2位校驗碼計算: - 在1位校驗碼的基礎上再計算一次校驗碼,計算出的結果即為第2位校驗碼,然后將第二位的校驗碼也附加到條碼數(shù)據(jù)的末尾。
計算代碼示例:
//計算第一位校驗碼
SStringW sstrContent = L"123456";
std::vector<int> vecCheckOne;
int nLength = m_sstrContent.GetLength();
for (int i = 0; i < nLength; i++)
{SStringW sstrChar = m_sstrContent.GetAt(i);if (sstrChar == L"-") vecCheckOne.push_back(10);else{int nChar = std::stoi(sstrChar.c_str());vecCheckOne.push_back(nChar); }
}int nTmp = 0;
for (int i = 0; i < vecCheckOne.size(); i++)
{nTmp += (vecCheckOne.size() - i) * vecCheckOne[i];
}
int nCheck = nTmp % 11;SString sstrCheck;
if (nCheck == 10) sstrCheck = L"-";
else sstrCheck.Format(L"%d", nCheck);//第二位校驗碼跟上邊計算一樣,用帶第一位的校驗碼數(shù)據(jù)再處理一次得出的結果即為第二位校驗碼。
//TODO: