1. 程式人生 > >“生成能夠被掃描槍正常掃描出中文的二維碼”

“生成能夠被掃描槍正常掃描出中文的二維碼”

擺在我眼前的是一個急需解決的問題,那就是生成能夠被掃描槍正常掃描出中文的二維碼。

這事情領導已經交代清楚,這是新客戶的需求,公司倉儲部能不能接下這個新專案,這一步很關鍵,儘管前一天我接到這個任務時還感覺它根本不是個問題,但直到現在,這個問題依舊擺在我面前,它真的花費了我一些時間,而我尚未解決它。

二維碼

二維碼其實是個相對於條形碼的概念,條形碼是一維的,那二維碼自然就是二維的了,雖然二維碼有很多種,但我們平常說的二維碼99%(甚至無限接近100%)指的就是QR碼這種格式的二維碼,QR碼是一個日本人發明的,他在發明QR碼的時候是打算用於工業領域,他當時根本沒想到這種二維碼能夠在中國發揚光大乃至如今是無處不在,確實,QR碼是我用過的最好用的二維碼,我另外接觸的幾種二維碼,比如DataMatrix,或者PDF417等都是相當不友好的,第一是它們包含的內容受限,不支援漢字,其實這點還好,誰沒事會想著把漢字編進碼中?第二是它們的容錯性太差,稍微的汙染、遮擋都讓它們識別失敗,這點讓人難以忍受。QR碼還有個好處,就是可以做些花樣,比如改改顏色,把頭像或LOGO放中間,換個形狀,玩法多種多樣,如果有的選,我想不出任何使用QR碼以外的二維碼的理由。

QR碼怎麼讀取?當然是手機掃一掃。

 

掃出來的東西通常是一串字元,當然了,如何理解這串字元,那就要看掃碼軟體如何去解讀了,如果你用微信掃一掃,它可能把字元識別為一個付款碼,或者識別為一個網址,一個公眾號連結等,總之世間萬物不都可以用一串文字來標識嗎?

事實上,QR碼中是可以存放二進位制資料的,當然了,字元也完全可以按照不同的字元編碼轉變為二進位制資料,所以我們可以理解為:QR碼啥都能存,就看你的掃碼軟體怎麼解。

我的QR碼生成軟體用的是一些開源的程式碼,再經過自己打磨一番做成的,對漢字的處理,是按照UTF-8編碼轉為二進位制,進而存放到QR碼中。不管是微信,還是手機預設的掃碼程式,都能順利檢出其中的中文——我認為我生成的二維碼是沒問題的。

編碼

那接下來問題可能就只有一個,那就是編碼問題,我使用了UTF-8編碼,因為UTF-8是世界乃至宇宙通用的編碼,它能容納下所有人類文字,如果可以選,我想不出任何不使用UTF-8而是使用別的編碼的理由。


(UTF-8已經事實上一統江湖)

但由於一些歷史慣性,當前有好些中文文字,還是按照GBK編碼去做的,GBK即國(G)標(B)擴(K)展,它是對GB2312編碼的擴充套件,但如今說GBK和GB2312其實都是同一回事,有時候簡稱GB碼,是較早期的漢字編碼格式。

掃描槍可能不認UTF-8,但認GBK。

用GBK替代UTF-8嗎?不,前面做的功能必須要相容,於是我在我的QR碼生成軟體中增加了一個選項,允許使用者選擇QR碼的中文編碼格式,有UTF-8和GB2312可以選,當然了,預設是UTF-8。功能很快就完成了,但倉儲部的試驗的結果很快就否定了我這一做法——依舊還是不行。

HID

“掃描槍其實是個HID裝置”,這句話是許多年前的一個同事跟我說的,當時公司需要做一個軟體,掃描槍一掃條碼,它就自動把掃到的內容填入程式的某個輸入框中,我當時的問題是:假如我的輸入焦點不在要錄入的那個輸入框中,那我如何識別出這個輸入是來自掃描槍的,並做妥當處理?同事說這是不可行的,他解釋道:“所謂HID,就是人機介面裝置(Human Interface Device),鍵盤就是個HID,掃描槍對我們的應用程式來說,跟一把普通鍵盤沒有什麼不同,你可以認為它就是模擬個鍵盤那樣,模擬敲擊幾個按鍵,把內容帶到輸入框裡。”


(普通掃描槍)

我很快了解了原理,但心有不甘,於是想出了一個投機取巧的辦法,能夠讓程式“智慧”識別出這個輸入來自掃描槍:我經過觀察,發現我們要掃的條碼內容的長度是一樣的,且前幾個字元都是一樣的,更關鍵的是每個字元的錄入間隔在20-30毫秒之間,人通過鍵盤敲擊錄入的內容絕對不會那麼快且間隔均勻,於是有辦法了,我弄了一個鍵盤鉤子,捕捉鍵盤錄入資訊,根據這個錄入的規律來判斷一串字元是不是通過掃描槍錄入的,接下來就是一些細節處理了,這任務我完成得很出色……這是許多年前的事情了,這件往事堪稱workaround的典範,許多年後跟朋友提起這個依然覺得那麼有趣。

而今,倉儲部的程式並不是我寫的,我只是應要求解決他們這麼一個問題:如何做出讓掃描槍正常掃出中文的QR碼?

“不行,我需要一把掃描槍”,於是讓人從倉儲部捎了一把過來。

說明書

一天後,掃描槍來到了我的辦公桌上,我接上電腦後,拿起它隨便一掃,嗯?怎麼只聞“Bee”聲,不見錄入,倉儲部的人說這是免驅動的,且我也沒在裝置管理器中看到衝突,很奇怪,我換了幾臺機器,一模一樣,難道是因為倉儲部用的是Windows7,而我們用的是Windows10導致的?於是我熟練地開啟VMWare,執行起跑著Windows7的虛擬機器,將裝置連線至虛擬機器,然而結果一樣,還是不行。於是找驅動程式,這是大廠“霍尼韋爾”的產品,但下載驅動卻十分十分不友好,首先是網站開啟慢且凌亂,非常不人性化,其次是好不容易找到下載點卻提示要註冊,再次,註冊好之後發覺居然需要它官方的下載器配合瀏覽器的外掛來才能下載!我去!我只是想下個驅動,給我搞出這麼多事情來,外企真就是這副德性——傲慢,而且我後面發現我下的驅動安裝複雜,更關鍵的的是根本沒法用,我怒氣衝衝想解除安裝它的時候發覺卸載出錯……我說我說,那些迷信國外品牌比國產強的,多用腦子想想,我們早已經是一個工業強國,再說掃描槍這種技術含量也不算高的東西難不成真做不好?


(就是這貨 霍尼韋爾 Xenon 1900)

我開啟裝置管理器,發現這個裝置被識別為一個串列埠裝置,這也難怪了,於是我開啟串列埠除錯工具,開啟串列埠,果然能讀取到掃描槍掃描的內容。這支掃描槍並不是HID啊,我默唸道……難道倉儲部的應用程式有針對串列埠的程式設計?問了之後明確回答是沒有。那就還只可能有一個原因了:這個掃描槍有不同的工作模式。

於是我費了不少力氣找到了它的說明書,果然!它有好幾種模式,其中一種是HID模式,這是我們想要的,切換模式通過掃描說明書上的條碼來完成。但是又遇到了問題,說明書是電子檔的,掃描槍幾乎掃不了我螢幕上的內容,於是列印了幾張紙,這個任務總算完成了,回頭一看時間都過去了幾個小時……

在設定完HID模式後,我試了一下,發覺如果QR碼中包含了中文的話,掃描槍掃出的內容會跳過中文,但英文和數字是能出來的,很顯然,這需要設定掃描槍的字元編碼格式,即Encoding,我很快在說明書上找到了相關說明,心想這回總算要大功告成了吧。切換掃描槍的編碼格式同樣是通過掃描說明書上特定的條碼完成,說明書還真的挺重要的。

但接下去我依舊是No luck,中文依舊是掃不出來,當然了,這中間當然免不了多次嘗試,一不小心就到了晚上……

不可行

這時候,我只有一個念頭,能不能換把掃描槍試試,別用什麼國際大牌了,就隨便弄個山寨貨估計就行了。夜已深,回家了,先不弄了。

在實際的工作中,我發現一個規律,當一個問題苦思冥想得不到解決的時候,常常是去上個廁所,就想到了解決或者變通方案,所以又有一種說法是人在廁所裡的大腦是最活躍,思維速度是最快的,你不見那些手遊的記錄都是在廁所裡創造出來的麼?只不過這次不是在廁所,只是在回家路上,突然想起了個事情:既然掃描槍和鍵盤的工作模式一樣,那通過敲擊鍵盤的按鍵,能直接輸入中文嗎?——這不可能啊,哈哈!我們的中文輸入,依賴的是輸入法(IME),而鍵盤能輸入的僅僅是字母數字和一些特殊符號,特殊符號在不同的語言環境下可能有區別,這才有了前面提到的掃描槍的編碼格式,這些大多是針對西歐文字的,對於中文,那絕對是無能為力。因此,這從頭到尾就是個偽命題啊,我的結論就是:沒辦法用HID掃描槍掃描出QR中的中文。

接下來的問題就是倉儲部客戶那邊是怎麼提出這個需求的?難道他們曾經用HID掃描槍掃描出了QR碼中的中文?我直接聯絡不上客戶,而讓倉儲部去問又說不清,我於是把這個事情如此般描述:不帶額外程式設計的話,掃描槍是掃描不出二維碼中的中文的。

當然了,要跟非技術人員講清楚技術問題是蠻難的,我補充了一句:“原理上不可能。”“知道了,就是說世界上沒有一把掃描槍能掃出中文對吧?”這句話相當不嚴謹,但我覺得我不能再解釋下去,否則更加說不清,於是非常肯定地說:“是的。”


Case closed,繼續搬磚。