步驟1:了解格式
磁性編碼條帶數據遵循通用標準。磁條由3條物理上分開的“磁道”組成。磁道1最靠近卡的底部,磁道3最高。 Square的讀取器位于讀取軌道2的位置。軌道2是最常用的軌道,但是大多數信用卡也使用軌道1。軌道2包括卡號和有效期。音軌1包括那個加號。根據特定的卡,可能還會有其他數據。這些磁道的寬度規定為0.11英寸,因此要使用Square的讀取器讀取磁道1,我們只需要重新布置條紋,使磁道1與讀取頭對齊即可。
每個磁道中的數據均通過磁編碼域翻轉。長話短說:一系列的域翻轉對波形進行編碼,該波形被解釋為二進制。此編碼中的二進制0是任意頻率。 1是該頻率的兩倍。
數據以一組前導零開始,以建立基本頻率。在可變數目的零之后,出現開始標記。對于音軌2,開始標記為“;”。每個字符被編碼為整數,最低有效位在前。對于磁道2,每個字符包含4個數據位和1個奇偶校驗位。為每個字符設置奇偶校驗位,以使1的數量為奇數。如果為每個字符的整數值加上48(ASCII編碼為“ 0”),則將顯示ASCII字符。除了數字“ 0”到“ 9”之外,磁道2還可以編碼一些其他字符,包括“;”。 (開始標記),“ =“(字段分隔符)和“?” (末尾)。
步驟2:制作墊片以讀取音軌1
磁卡的磁道1比磁道2更靠近卡的邊緣.11英寸。由于Square讀卡器被設置為讀取磁道2,因此如果我們在磁道中粘貼一些東西,讀取器將卡提升.11英寸時,讀取頭將與軌道1對齊,而不是與軌道2對齊。
您可以通過從另一張卡上剪切0.11英寸的條來創建墊片。我還發現廉價垃圾袋的纏結也差不多。
第3步:錄制一些音頻
就電話而言,Square閱讀器只是一個麥克風。因此,要從卡中獲取數據,我們需要記錄音頻。請參閱其他Android文檔(例如本教程:http://eurodev.blogspot.com/2009/09/raw-audio-manipulation-in-android.html)以獲取詳細說明,或使用RhombusLib(請參閱最后的鏈接) )。以下是一些Java代碼,可以開始在Android應用中記錄音頻:
AudioRecord audioRecord =新的AudioRecord(MediaRecorder.AudioSource.MIC,
頻率,channelConfiguration,
audioEncoding,bufferSize);
audioRecord.startRecording();
錄音時,我們需要不斷從錄音機中讀取數據并將其放入緩沖區中。
//創建一個DataOutputStream以寫入音頻數據
ByteArrayOutputStream os = new ByteArrayOutputStream ();
BufferedOutputStream bos =新的BufferedOutputStream(os);
DataOutputStream dos =新的DataOutputStream(bos);
short bufferVal;
short [] buffer = new short [bufferSize];
while(recording){
bufferReadResult = audioRecord.read(buffer,0,bufferSize);
for(int i = 0; i bufferVal = buffer [i];
dos.writeShort(buffer [i]);
}
}
dos.close();
byte [] audioBytes = os.toByteArray();
上面的代碼是從RhombusLib中提取并簡化的。錄制后,您將擁有一個字節數組,代表麥克風中的樣本,可以進行分析。
步驟4:解碼音頻
因此,現在我們的設備上有很多音頻。我們如何解碼它?我的代碼基于Android教程,該教程顯示了如何記錄數據然后進行回放。就我而言,我確保將音頻保存為16位PCM編碼。我以44100hz采樣。在Android(以及其他地方,我想)上,16位PCM數據意味著每個樣本都是一個帶符號的16位值。因為我們只關心頻率,所以我們只需要關心“零交叉”之間有多少時間。過零是指信號從正向變為負,反之亦然。 0位將由2個交叉點之間的間隔表示,而1將在大約相同的時間段內有一個額外的交叉點。
每個磁道中的卡數據以一些(可變)數0開始,以建立基本頻率。我所做的是聽取高于某個“安靜”閾值的第一個樣本,然后計算零交叉之間的樣本數。該數字將成為0的基值。由于這些卡是手工刷卡的,因此從掃描開始到結束,實際頻率將有所變化。因此,我做了一個簡單的方法,確定自上次零交叉以來的樣本數量是否更接近基本頻率或兩倍于基本頻率(基本樣本數量的一半)。然后,它會相應地調整預期的基本頻率。只要兩個邏輯位之間的變化很小,此方法就可以很好地工作。而且它們幾乎肯定會。
要檢測零交叉,我們需要查看每個樣本的符號并將其與前一個樣本的符號進行比較。如果它們不同(一個正,一個負),則信號在這些樣本之間越過0。
基本算法是遍歷字節數組,提取樣本。計算零交叉之間的樣本數,并將其與0或1的預期計數進行比較。好的,經過一番揮舞之后,我們現在有了一個二進制數據序列,我們想回過頭來。轉換成ASCII。最常見的編碼(也是我編寫的唯一處理程序)將每個字符編碼為一定數量的位,再加上一個奇偶校驗位。對于音軌2,字符為4位,奇偶校驗為1,組成5位組。從最低有效位到最高讀取位,最后一位是奇偶校驗位。將奇偶校驗位設置為使組中的1的個數為奇數。在我的實現中,我只是忽略了奇偶校驗位,但這將有助于確定讀取是否正確。在磁道1中,字符的6位加上奇偶校驗。
磁道的字符集也有所不同,但是兩者都是ASCII子集,具有一些偏移量。對于僅編碼一些符號和數字的磁道2,字符集從48開始,這是“ 0”的ASCII碼。因此,如果我們得到0,0,0,0,1作為我們的角色,則將其變成0,加48,得到48。類似地,1,0,0,0,0為1。1 + 48 = 49 = ASCII“ 1”。
對于軌道1,字符集以“”(空格)開頭,即ASCII32。因此,我們在解碼的數字值上加上32,得到ASCII字符。之后,我們有了數據,因此剩下的一切都只是在掛接UI膠水。
責任編輯:wv
-
Android
+關注
關注
12文章
3937瀏覽量
127500 -
BSQUARE
+關注
關注
0文章
5瀏覽量
8758 -
磁條卡
+關注
關注
0文章
8瀏覽量
6878
發布評論請先 登錄
相關推薦
評論