waysun一路陽光

          不輕易服輸,不輕言放棄.--心是夢的舞臺,心有多大,舞臺有多大。踏踏實實做事,認(rèn)認(rèn)真真做人。

            BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 ::  :: 管理 ::
            167 隨筆 :: 1 文章 :: 64 評論 :: 0 Trackbacks
          轉(zhuǎn)自:http://www.itpub.net/419521.html

          我剛進(jìn)入金融行業(yè)時,就知道了IS08583報文協(xié)議,我想可能我還沒進(jìn)入這個行業(yè)都已經(jīng)聽過了,可知ISO8583的影響力有多大了。最初剛接觸它時,確實對其中的一些細(xì)節(jié)概念不是很清晰,對有些地方比較迷惑。鑒于此,我想很多同行也必然會經(jīng)歷同樣得階段,所以我寫下本文,以便大家能夠少走一些彎路。同時,我在網(wǎng)上( http://blog.csdn.net/lysheng/archiv.../03/309914.aspx )寫下我要寫“全面掌握ISO8583報文”和“符合CEN/XFS(即WOSA/XFS)規(guī)范的SP編寫”兩篇文章時,很多人都詢問我什么時候能夠?qū)懗鰜恚芍S多人是需要了解這方面的知識的,即使我時間不是很多,也得盡量將這兩篇文章寫出來,給需要的人提供一些參考。

          如果單純的講IS08583那些字段的定義,我覺得沒有什么意思,標(biāo)準(zhǔn)中已經(jīng)對每個字段解釋的非常詳細(xì)了,如果你覺得理解英文版的ISO8583規(guī)范有些困難,網(wǎng)上也有同行為我們翻譯好的中文版ISO8583規(guī)范,所以我的目的是達(dá)到閱讀本文后能夠?qū)SO8583知其然,亦知其所以然,使以前基本沒有接觸它的人也能夠達(dá)到掌握ISO8583報文規(guī)范。


          好了,我們該轉(zhuǎn)入正題了。

          最開始時,金融系統(tǒng)只有IBM這些大的公司來提供設(shè)備,象各種主機(jī)與終端等。在各個計算機(jī)設(shè)備之間,需要交換數(shù)據(jù)。我們知道數(shù)據(jù)是通過網(wǎng)絡(luò)來傳送的,而在網(wǎng)絡(luò)上傳送的數(shù)據(jù)都是基于0或1這樣的二進(jìn)制數(shù)據(jù),如果沒有對數(shù)據(jù)進(jìn)行編碼,則這些數(shù)據(jù)沒有人能夠理解,屬于沒有用的數(shù)據(jù)。起初的X.25、SDLC以及現(xiàn)在流行的TCP/IP網(wǎng)絡(luò)協(xié)議都提供底層的通訊編碼協(xié)議,它們解決了最底層的通訊問題,能夠?qū)⒁淮址麖囊粋€地方傳送到另一個地方。但是,僅僅傳送字符串是沒有太大意義的,怎樣來解析字符串代表什么內(nèi)容是非常重要的,否則傳送一些“0123abcd”的字符串也是無用的亂碼。

          讓我們隨著時光回到幾十年前的某個時刻,假設(shè)我們被推到歷史的舞臺上,由我們來設(shè)計一個通用報文協(xié)議,來解決金融系統(tǒng)之間的報文交換,暫且稱該協(xié)議叫做ISO8583 協(xié)議。此時,技術(shù)是在不斷的前行,當(dāng)初IBM一支獨(dú)秀的局面好像已經(jīng)不妙了,各種大小不一的公司都進(jìn)入金融行業(yè)以求能有所斬獲,呈一片百花齊放的局面。我們怎樣來設(shè)計一個報文協(xié)議,能夠?qū)⑦@些如雨后春筍般出現(xiàn)的所有公司都納入進(jìn)來,其實也不是一件很簡單的事。

          我們還是先一步步的來考慮吧。金融行業(yè)其實涉及到的數(shù)據(jù)內(nèi)容并不是成千上萬,無法統(tǒng)計,恰恰相反,是比較少的。我們都可以在心底數(shù)得過來,象交易類型、帳號、帳戶類型、密碼、交易金額、交易手續(xù)費(fèi)、日期時間、商戶代碼、2磁3磁數(shù)據(jù)、交易序列號等,把所有能夠總結(jié)出來的都總結(jié)起來不過100個左右的數(shù)據(jù)。那我們可以首先簡單的設(shè)計 ISO8583,定義128個字段,將所有能夠考慮到的類似上面提到的“帳號”等金融數(shù)據(jù)類型,按照一個順序排起來,分別對應(yīng)128個字段中的一個字段。每個數(shù)據(jù)類型占固定的長度,這個順序和長度我們都事先定義好。這樣就簡單了,要發(fā)送一個報文時,就將128個字段按照順序接起來,然后將接起來的整串?dāng)?shù)據(jù)包發(fā)送出去。

          任何金融軟件收到ISO8583包后,直接按照我們定義的規(guī)范解包即可,因為整個報文的128個字段從哪一位到哪一位代表什么,大家都知道,只要知道你的數(shù)據(jù)包是ISO8583包即可,我們都已經(jīng)定義好了。比如第1個字段是“交易類型”,長度為4位,第2個字段位是“帳號”,為19位等等。接收方就可以先取4位,再取接著的19位,依次類推,直到整個數(shù)據(jù)包128個字段都解完為止。

          其實這種做法真是簡單直接,基本上就可以滿足需要了。不過我們有幾個問題要思考下:
          1、 我怎么知道每個字段的數(shù)據(jù)類型呢,是數(shù)字還是字符?
          2、 每個傳送的報文都把128個字段都傳過去,那網(wǎng)絡(luò)帶寬能夠承受得了,有時候我可能只需要其中5個字段,結(jié)果多收到了123個無用的字段。
          3、 如果我某些字段的長度不固定,屬于變長怎么辦,因為你現(xiàn)在解包是當(dāng)作數(shù)據(jù)包每個字段都是固定的,用C語言解包時直接依靠指針取固定長度的一串字符做為一個字段。

          我們來一一解決這些問題。

          第一個問題簡單,我在定義ISO8583時除了定義每個字段表示什么,還規(guī)定其內(nèi)容是數(shù)字或是字符等即可。考慮可能出現(xiàn)的類型不過有以下幾種:字母、數(shù)字、特殊字符、年月日等時間、二進(jìn)制數(shù)據(jù)。比如我對128個字段中的“商戶類型”字段定義其長度是15,同時定義其類型為字母。再精細(xì)點,如果“商戶類型”里面的數(shù)據(jù)同時包括數(shù)字和字母呢?那我們就定義其類型為字母也可,為數(shù)字也可,即一個字段可以同時屬于多個類型。

          第二個問題稍微復(fù)雜點。其本質(zhì)就是如果我只傳128個字段的5個字段,接收方怎么知道我傳了哪幾個字段給它了。要是我們把剩下的123全部填成0或其他特殊標(biāo)識,標(biāo)明該字段不需要使用?這種處理方法沒有半點用處,沒有解決網(wǎng)絡(luò)帶寬的本質(zhì)問題,還是要傳128個字段。

          換個思路,我在報文前面加上個包頭,包頭里面包含的信息能夠讓別人知道只傳了5個字段。怎樣設(shè)計這個包頭,可以這樣,我們用16個字節(jié),即128個 bit(一個字節(jié)等于8bit)來表示128個字段中的某個字段是否存在。每個bit在計算機(jī)的二進(jìn)制里面不是1就是0,如果是1就表示對應(yīng)的字段在本次報文中存在,如果是0就是不存在。這樣好了,如果別人接收到了ISO8583報文,可以先根據(jù)最前面的報文頭,就知道緊接著報文頭后面的報文有哪些字段,沒有哪些字段了。比如,我要發(fā)送5個字段,分別屬于128個字段中的第2、3、6、8、9字段,我就可以將128bit的報文頭填成 011001011000000000………..,一共128個bit,后面就全是0了。注意其中第2、3、6、8、9位為1,其他都為0。

          有了這個128bit的報文頭,我們就可以只發(fā)送需要的5個字段了。怎樣組織報文?先放上這128bit,即16個字節(jié)的頭,然后在頭后面放2、3、6、 8、9字段,這些字段緊挨在一起,3和6之間也不需要填上4、5這兩個字段了。接收方收到這個報文,它會根據(jù)128bit的報文頭來解包,它自然知道把第 3個字段取出后,就直接在第3字段的后面取第6個字段,每個字段的長度在ISO8583里面都定義好了,很輕松就把數(shù)據(jù)包解出來了。

          這下好了,為了解決上面的第二問題,我們只是在報文中增加了16個字節(jié)的數(shù)據(jù),就輕松搞定了,我們把這16個字節(jié)稱為bit map,即位圖,用來表示某個位是否存在。不過我們再稍微優(yōu)化一下,考慮到很多時候報文不需要128個字段這么多,其一半64個字段都不一定能夠用完。那我可以將報文頭由128bit減到64bit,只有在需要的時候才把剩下的64bit放到報文里面,這樣報文長度不又少了8個字節(jié)嗎?

          是個好主意。我們把ISO8583的128個字段中最常見的都放到前64個字段中,那我們可以將處理縮小一倍。這樣我一般發(fā)送報文時只需發(fā)送64bit,即一個字節(jié)的報文頭,再加上需要的幾個字段就可以了。如果有些報文用到64到128之間的字段呢?這個也好辦,我把64bit報文頭的第一位bit用來代表特殊含義,如果該bit為1,則表示64bit后面跟了剩下的64bit報文頭;如果第一位bit為0,則表示64bit后面沒有跟剩下的64bit報文頭,直接是128個字段中的報文了。那們,接收方會判斷一下報頭的第一個bit是1還是0,從而知道報文頭是64bit還是128bit了,就可以做相應(yīng)處理。因為報文頭第二個64bit屬于有時候有,所以我們叫它Extended bit map擴(kuò)展位圖,相應(yīng)的報文頭最開始的64bit我們叫它Primary bit map主位圖。我們直接把擴(kuò)展位圖固定放到128個字段的第一個字段,而主位圖每個數(shù)據(jù)包都有,就強(qiáng)制性放在所有128個字段的前面,并不歸入128個字段中去。

          第三個問題可以考慮這樣解決。比如第2個字段是“帳號”,是不定長的,可能有的銀行帳號是19位,有的是17位等。我們定 ISO8583規(guī)范時可以規(guī)定第2個字段是25位,這下足夠?qū)?9和17的情況都包含進(jìn)來,但是如果以后出現(xiàn)了30位的怎么辦?那我們現(xiàn)在將字段定為 100位。以后超過100位怎么辦,況且如果你只有19位的帳號,我們定義了100位,那81位的數(shù)據(jù)不是浪費(fèi)了網(wǎng)絡(luò)的帶寬。看來預(yù)先定義一個我們認(rèn)為比較大的位數(shù)是不太好的。

          我們這樣,對于第2個字段“帳號”,在字段的開頭加上“帳號”的長度。比如帳號是0123456789,一共10 位,我們變成100123456789,注意前面多了個10,表示后面的10位為帳號。如果你接觸過COM里面的BSTR,應(yīng)該對這種處理比較熟悉了。接收方收到該字段后,它知道ISO8583規(guī)定第2個字段“帳號”是變長的,所以會先取前面的2位出來,獲取其值,此時為長度,然后根據(jù)該長度值知道應(yīng)該拷貝該字段后面哪幾位數(shù)據(jù),才是真正的帳號。如果你覺得長度如果只有兩位最多只能表示99位長,不太夠,我們也定義可以允許前面3位都為長度的變長字段,這樣就有999位長,應(yīng)該夠了吧。在規(guī)范里面如果我定義某個字段的屬性是“LLVAR”,你注意了,其中的LL表示長度,VAR表示后面的數(shù)據(jù),兩個LL表示兩位長,最大是99,如果是三位就是“LLLVAR”,最大是999。這樣看我們定義的ISO8583規(guī)范文檔時直接根據(jù)這幾個字母就理解某個變長字段的意思了。

          該解決的幾個問題到這里都解決了,我們來回顧下自己設(shè)計的ISO8583規(guī)范。其實沒有什么,無非是把金融行業(yè)可能出現(xiàn)的數(shù)據(jù)分門別類,排好順序,接著把它們連接起來,組成一個報文發(fā)送出去而已。其中針對該報文的設(shè)計進(jìn)行了一些優(yōu)化,引入了bit map位圖的概念,也算是一個不錯的想法。

          剩下的工作就簡單了,我們就直接收集金融行業(yè)可能出現(xiàn)的數(shù)據(jù)字段類型,分成128個字段類型,如果沒有到128個這么多就先保留一些下來,另外考慮到有些人有特殊的要求,我們規(guī)定可以將128個字段中的幾個字段你自己來定義其內(nèi)容,也算是一種擴(kuò)展了。

          這樣,最后我們就得到了ISO8583規(guī)范的那張字段描述表了。想要詳細(xì)的知道每個字段的含義直接對著表看就可以,比較簡單。

          全文完


          劉永勝        2005年于迪堡廣州
          posted on 2010-05-20 14:31 weesun一米陽光 閱讀(709) 評論(0)  編輯  收藏 所屬分類: 收藏的文章
          主站蜘蛛池模板: 栾城县| 九龙城区| 柳江县| 梅州市| 罗源县| 成武县| 康乐县| 科技| 岫岩| 陇南市| 陕西省| 江门市| 桂东县| 五寨县| 资源县| 嘉祥县| 沧源| 绥德县| 寿宁县| 错那县| 岳阳市| 乌拉特前旗| 稷山县| 滨州市| 东丽区| 姜堰市| 平果县| 行唐县| 大丰市| 锦屏县| 旬邑县| 诏安县| 寻乌县| 南投市| 宜兰县| 白朗县| 余江县| 福州市| 岳阳市| 靖宇县| 利津县|