`
fireflyjava
  • 浏览: 187319 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

银行系统中EBCDIC同GBK互转,Java的实现

    博客分类:
  • Java
阅读更多

 

银行系统中有的核心Core banking采用AS/400系统,而AS/400采用EBCDIC编码,所以渠道整合的时候就会涉及到转码的问题。避免冷僻字的问题, 采用GBK字符集

 

package com.ebcdic;

import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.util.LinkedList;
import java.util.Queue;
import java.util.TreeMap;
/**
 * 
 * @author Kevin
 * @since jdk1.5
 *
 */

public class EbcdicGbkConverter {
	
	final static String GBK_FILE="GBK_CVT.txt";
	final static String ebcdicCharsetName="Cp1047";
	
	private static TreeMap <Character,Integer> gbk2Ebcdic=new TreeMap<Character,Integer> ();
	private static TreeMap <Integer,Character> ebcdic2Gbk=new TreeMap<Integer,Character> ();
	
	private static char gbk2EbcdicChar[] ;
	private static int gbk2EbcdicInt[];
	
	private static char ebcdic2GbkChar[] ;
	private static int ebcdic2GbkInt[];
	
	static {
		try {
			initEbcdicGBKMapping();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	/**
	 * Initial the EBCDIC and GBK mapping
	 * @throws IOException
	 */
	private static void initEbcdicGBKMapping() throws IOException{
		
		InputStream input=EbcdicGbkConverter.class.getResource(GBK_FILE).openStream();
		BufferedReader reader=new BufferedReader(new InputStreamReader(input));
		String record;
		while((record=reader.readLine())!=null){
			char gbkChar=record.charAt(0);
			String ebcdicChar=record.substring(1, 5);
			Integer ebcdicInt=Integer.valueOf(ebcdicChar,16);
			gbk2Ebcdic.put(gbkChar, ebcdicInt);
			ebcdic2Gbk.put(ebcdicInt, gbkChar);			
		}		
		gbk2EbcdicChar=new char[gbk2Ebcdic.size()];
		gbk2EbcdicInt=new int[gbk2Ebcdic.size()];
		int index=0;
		for(Character c:gbk2Ebcdic.keySet()){
			gbk2EbcdicChar[index]=c.charValue();
			gbk2EbcdicInt[index++]=gbk2Ebcdic.get(c).intValue();
		}
		ebcdic2GbkChar=new char[ebcdic2Gbk.size()];
		ebcdic2GbkInt=new int[ebcdic2Gbk.size()];
		
		index=0;
		for(Integer i:ebcdic2Gbk.keySet()){
			ebcdic2GbkChar[index]=ebcdic2Gbk.get(i).charValue();
			ebcdic2GbkInt[index++]=i.intValue();
		}
		
		
	}
	private static boolean isEnglishChar(char c){
		if(c <0xFF )
			return true;
		else
			return false;
	}	
	/**
	 * convert the string into EBCDIC format
	 * @throws IOException 
	 */
	public static byte[] stringToEbcdic(String data) throws IOException{
		ByteArrayOutputStream out=new ByteArrayOutputStream();
		char dataChar[]=data.toCharArray();
		Queue<Integer> gbkQueue= new LinkedList<Integer>();
		String eng;
		for(int i=0;i<dataChar.length;i++){
			char c=dataChar[i];
			if(isEnglishChar(c)){
				if(gbkQueue.size()>0){
					readGBKQueue(out,gbkQueue);
				}
				eng=new String(new char[]{c});
				byte buff[]=eng.getBytes(ebcdicCharsetName);
				out.write(buff);
			}else{
				//the Dichotomy is faster than hash table
				//seaqueue.add(gbk2Ebcdic.get(c));
				//Add the Chinese Character in the queue first
				gbkQueue.add(midSearch(c));
			}
		}
		if(gbkQueue.size()>0){
			readGBKQueue(out,gbkQueue);
		}
		
		return out.toByteArray();
	}
	/**
	 * The Chinese character start with '0x0e' and end with '0x0f' in EBCDIC character set
	 * @param out
	 * @param queue
	 * @throws IOException
	 */
	private static void readGBKQueue(OutputStream out,Queue <Integer>queue) throws IOException{
		out.write(0x0e);
		Integer data;
		while((data=queue.poll())!=null){
			int dataInt=data.intValue();
			out.write((dataInt>>8)&0xff);
			out.write(dataInt&0xff);
		}
		out.write(0x0f);
	}
	/**
	 * Dichotomy to search 
	 * @param c
	 * @return
	 */
	private static int midSearch(char c){
		int start=0;
		int end=gbk2EbcdicChar.length-1;		
		while(start<=end){	
			int mid=(start+end)>>1;
			char midChar=gbk2EbcdicChar[mid];
			if(c>midChar){
				start=mid +1 ;
			}else if(c<midChar){
				end=mid -1 ;
			}else{
				return gbk2EbcdicInt[mid];
			}
		}
		return -1;
	}
	
	/**
	 * Dichotomy to search 
	 * @param c
	 * @return
	 */
	private static char midSearchEbcdicToGBK(int c){
		int start=0;
		int end=ebcdic2GbkInt.length-1;		
		while(start<=end){	
			int mid=(start+end)>>1;
			int midValue=ebcdic2GbkInt[mid];
			if(c>midValue){
				start=mid +1 ;
			}else if(c<midValue){
				end=mid -1 ;
			}else{
				return ebcdic2GbkChar[mid];
			}
		}
		return ' ';
	}
	/**
	 * Convert the EBCDIC to GBK format String 
	 * @param data
	 * @return
	 * @throws UnsupportedEncodingException
	 */
	public static String ebcdicToGBK(byte data[]) throws UnsupportedEncodingException{
		Queue<Integer>  ebcdicQueue= new LinkedList<Integer>();
		StringBuffer buff=new StringBuffer();
		for(int i=0;i<data.length;i++){
			int b=data[i]&0xff;
			if(b==0x0e){
				ebcdicQueue.add(data[++i]&0xff);
			}else if(b==0x0f){
				readEbcdicQueue(buff,ebcdicQueue);
			}else{
				if(ebcdicQueue.size()==0)
					buff.append(new String(new byte[]{data[i]}, ebcdicCharsetName));
				else
					ebcdicQueue.add(data[i]&0xff);
			}
		}
		return buff.toString();
	}
	private static void readEbcdicQueue(StringBuffer buff,Queue <Integer>ebcdicQueue){
		
		Integer data1;
		while((data1=ebcdicQueue.poll())!=null){			
			int data2=ebcdicQueue.poll();
			int data=(data1<<8)+data2;
			char c=midSearchEbcdicToGBK(data);
			buff.append(c);
		}
	}
	/** 
     * Convert the string to 16 Radix format
     */  

    public static String str2HexStr(String str) {  
      
        return byte2HexStr(str.getBytes());  

    }  
    
    public static String byte2HexStr(byte data[]) {  

        char[] chars = "0123456789abcdef".toCharArray();  
        StringBuilder sb = new StringBuilder("");
        byte[] bs = data;  
        int bit;  
        for (int i = 0; i < bs.length; i++) {  
            bit = (bs[i] & 0x0f0) >> 4; 
            sb.append(chars[bit]);  
            bit = bs[i] & 0x0f;  
            sb.append(chars[bit]); 
            sb.append(" ");
        }  
        return sb.toString();  

    }  

 


	/**
	 * @param args
	 * @throws IOException 
	 */
	public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub
		
		EbcdicGbkConverter con=new EbcdicGbkConverter();
		
		byte buff[]=null;
		buff=EbcdicGbkConverter.stringToEbcdic("AS400 Ebcdic Converter Testing");			
		System.out.println("EBCDIC:["+byte2HexStr(buff)+"]");
		
		String st=EbcdicGbkConverter.ebcdicToGBK(buff);
		System.out.println("Eng:"+st);
		
		
		buff=EbcdicGbkConverter.stringToEbcdic("AS400 Ebcdic Converter Testing 冷僻字测试-镕");			
		System.out.println("EBCDIC:["+byte2HexStr(buff)+"]");
		
		st=EbcdicGbkConverter.ebcdicToGBK(buff);
		System.out.println("GBK:"+st);
		

	}

}

 

备注:

GBK_CVT.txt 文件

国4d9bb9fa
第一位:中文字符
第二位到第五位:16进制的EBCDIC码
第六位到第九位:16进制的GBK码

 

附录: GBK同EBCDIC的对应表文件GBK_CVT.txt 从如下URL下载

http://www.900.ibm.com/cn/support/viewdoc/detail?DocId=2222001000000 

 

 

分享到:
评论

相关推荐

    EbcdicGbkConverter_ebcdic_ebcdic查看工具_源码

    ebidic转码,提供了java的测试程序,仅供参考,本人挪用

    ssis中实现ebcdic 到 ascii的转换控件

    本文将详细介绍如何在SSIS中实现EBDIC到ASCII的转换,并探讨相关知识点。 EBDIC是一种主要在IBM大型机系统中使用的字符编码,而ASCII则广泛应用于个人电脑和网络。由于两者编码方式不同,直接处理可能导致乱码或...

    ebcdic转ascii

    ebcdic编码与ascii编码互转,仅供参考,如果用于报文编码转换,需进行字段拆解转码,否则会造成报文长度错误

    EBCDIC码与ASCII码转换处理源代码

    IBM MainFrame(AS400,S/390)与UNIX/Windows之间的编码转换

    ssis中ebcdic 到ascii码的转换控件

    EBDIC(Extended Binary Coded Decimal Interchange Code)是一种IBM大型机和小型机系统中广泛使用的字符编码方式,而ASCII(American Standard Code for Information Interchange)是基于拉丁字母的一套电脑编码...

    Ebcdic和ASCII字符对照表

    - **EBCDIC**:由IBM公司于1960年代开发,主要用于其大型机系统中。EBCDIC使用8位二进制码表示一个字符,可以支持更多的字符集,包括多语言和特殊符号。 - **ASCII**:创建于1963年,是一种7位编码标准,最初用于...

    ASCII EBCDIC 编码表

    ASCII(American Standard Code for Information Interchange,美国信息交换标准代码)和EBCDIC(Extended Binary Coded Decimal Interchange Code,扩展二进制码十进制交换码)是两种早期广泛使用的字符编码系统,...

    ebcdic.rar_conversion_ebcdic

    标题中的"ebcdic.rar_conversion_ebcdic"表明这是一个关于EBCDIC编码转换的压缩包文件,其中可能包含了实现EBCDIC(Extended Binary Coded Decimal Interchange Code)与ASCII(美国标准信息交换代码)之间相互转换...

    iso8583协议的java实现

    在Java中,通常使用BitSet类来处理这些位图,根据位图的值决定如何处理后续字段。 3. **编码与解码**:ISO8583协议支持多种编码方式,如ASCII、EBCDIC等。在Java实现中,需要考虑如何将字符数据转换为二进制,以及...

    Ebcdic和ASCII字符对照表.zip

    在实际应用中,如果你需要在支持ASCII编码的系统和使用EBCDIC编码的系统之间交换数据,就需要理解和使用这样的对照表。例如,如果你在处理来自IBM大型机的数据,这些数据可能是EBCDIC编码的,而你的现代计算机系统...

    EBC和ASCII码转换

    由于历史原因,EBCDIC在IBM的大型主机系统中仍然广泛使用。 **ASCII码**,则是一种7位的字符编码,最初于1963年发布,包含128个字符,包括大小写字母、数字、标点符号以及控制字符。ASCII码的设计目标是通用性和...

    EBCDIC编码表

    EBCDIC编码,ASCII码与EBCDIC编码进行转换的编码表

    Ebcdic-ascii 对照表.

    Ebcdic-ascii 对照表. UTF-EBCDIC is a character encoding used to represent Unicode characters. It is meant to be EBCDIC-friendly, so that legacy EBCDIC applications on mainframes may process the ...

    Java IO

    Java 输入/输出 (I/O) 系统是 Java 编程语言中的一个关键组成部分,它为程序员提供了与不同类型的输入输出设备交互的能力。Java I/O 的设计考虑到了跨平台性和灵活性,但这也使得它的使用变得相对复杂。 ##### 为...

    conv_gbk_ibm1388:GBKIBM1388字符集转换

    GBK / IBM1388字符集转换GBK是PC上使用的主要简体中文字符集,而IBM1388在大型机上。 这两个字符集不能通过像Unicode在UTF-8和UTF-16之间所做的操作来直接互换。 它们基于具有不同汉字顺序的不同编码(ASCII / ...

    ebcdic-ascii-converter-0.1.jar

    jar包,官方版本,自测可用

    IBM大型机与小型机间汉字转换解决方案

    2. **CICS配置优化**:虽然不依赖于额外的CICS程序,但仍然需要对CICS配置进行适当的调整,以确保Java程序能够顺利地与CICS系统集成,实现数据的有效传输。 #### 实现细节 - **编码转换机制**:无论是通过CICS程序...

Global site tag (gtag.js) - Google Analytics