Преобразовать строку из ASCII в EBCDIC в Java?

Мне нужно написать «простую» утилиту для преобразования из ASCII в EBCDIC?

Ascii идет от Java, Web и переходит на AS400. У меня был Google, похоже, не могу найти простого решения (возможно, потому что его нет :(). Я надеялся на утилиту с открытым исходным кодом или заплатил за утилиту, которая уже была написана.

Может быть, вот так?

Converter.convertToAscii(String textFromAS400)
Converter.convertToEBCDIC(String textFromJava)

Спасибо,

Скотт

Вам приходится иметь дело с переопределением и упакованными записями, или это прямая трансляция?

kemiller2002 15.12.2008 18:11
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
18
1
85 113
10
Перейти к ответу Данный вопрос помечен как решенный

Ответы 10

Должно быть довольно просто написать карту для набора символов EBCDIC и одну для набора символов ASCII, и в каждом из них возвращать символьное представление другого. Затем просто переберите строку для перевода, найдите каждый символ на карте и добавьте его в строку вывода.

Я не знаю, есть ли в открытом доступе какой-либо конвертер, но на его написание не уйдет больше часа.

Вы можете создать его самостоятельно с помощью этого таблица перевода.

Но здесь - это сайт, на котором есть ссылка на пример Java.

Вторая ссылка мертва. Вы знаете, куда это делось? Вы можете разместить здесь пример?

Bill the Lizard 08.11.2011 21:35

Вы должны использовать набор символов Java Cp1047 (Java 5) или Cp500 (JDK 1.3+).

Используйте конструктор String: String(byte[] bytes, [int offset, int length,] String enc)

Вы забыли Cp037 (он у нас есть). Вы должны предложить человеку проверить, какой набор символов используется.

Dominique Fortin 21.08.2017 19:19
Ответ принят как подходящий

JTOpen, версия IBM с открытым исходным кодом своего набора инструментов Java, имеет набор классов для доступа к объектам AS / 400, включая FileReader и FileWriter для доступа к собственным текстовым файлам AS400. Это может быть проще в использовании, чем писать собственные классы преобразования.

С домашней страницы JTOpen:

Here are just a few of the many i5/OS and OS/400 resources you can access using JTOpen:

  • Database -- JDBC (SQL) and record-level access (DDM)
  • Integrated File System
  • Program calls
  • Commands
  • Data queues
  • Data areas
  • Print/spool resources
  • Product and PTF information
  • Jobs and job logs
  • Messages, message queues, message files
  • Users and groups
  • User spaces
  • System values
  • System status

Мы используем панель инструментов JTopen, и она выполняет некоторую часть преобразования / сопоставления, просто кажется, что неправильно сопоставляет £, $, [и ^

scottyab 16.12.2008 13:56

Похоже, ваша AS / 400 неправильно настроена в отношении родного языка. Если он настроен правильно, jt400.jar не потребует никаких дополнительных настроек.

Thorbjørn Ravn Andersen 20.01.2009 15:05

Да, преобразование должно происходить в основном автоматически. Если это не так, что-то не так.

Mike Wills 26.03.2010 19:32

Обратите внимание, что String в Java содержит текст в собственной кодировке Java. При хранении в памяти «строки» ASCII или EBCDIC до кодирования в виде строки она будет находиться в виде байта [].

ASCII -> Java:   new String(bytes, "ASCII")
EBCDIC -> Java:  new String(bytes, "Cp1047")
Java -> ASCII:   string.getBytes("ASCII")
Java -> EBCDIC:  string.getBytes("Cp1047")

Существует множество кодовых таблиц EBCDIC. Исправлять вручную очень утомительно.

Thorbjørn Ravn Andersen 20.01.2009 15:06

Наборы символов Java, начинающиеся с "CP", относятся к IBM CCSID. Некоторую документацию по ним можно найти на www-03.ibm.com/systems/i/software/globalization/ccsid_list.h‌ tml, а www-03.ibm.com/systems/i/software/globalization/codepages.ht‌ мл CP1047, по-видимому, относится к 01047, «Latin 1 / Open Systems».

Alan Krueger 16.03.2012 20:32

@AlanKrueger на сегодняшний день эти ссылки мертвы. Это действительно плохо.

some_coder 18.10.2016 11:00

@some_coder - новая ссылка www-01.ibm.com/software/globalization/cp/cp_cpgid.html

VJ. 21.06.2017 09:08

Это то, что я использовал.

public static final int[] ebc2asc = new int[256];
public static final int[] asc2ebc = new int[256];

static
{
  byte[] values = new byte[256];
  for (int i = 0; i < 256; i++)
    values[i] = (byte) i;

  try
  {
    String s = new String (values, "CP1047");
    char[] chars = s.toCharArray ();
    for (int i = 0; i < 256; i++)
    {
      int val = chars[i];
      ebc2asc[i] = val;
      asc2ebc[val] = i;
    }
  }
  catch (UnsupportedEncodingException e)
  {
    e.printStackTrace ();
  }
}
package javaapplication1;

import java.nio.ByteBuffer;
import java.nio.CharBuffer;

import java.nio.charset.CharacterCodingException;

import java.nio.charset.Charset;

import java.nio.charset.CharsetDecoder;

import java.nio.charset.CharsetEncoder;

public class ConvertBetweenCharacterSetEncodingsWithCharBuffer {

    public static void main(String[] args) {

       //String cadena = "@@@@@@@@@@@@@@@ñâæÃÈÄóöó@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ÔÁâãÅÙÃÁÙÄ@ÄÅÂÉã@âæÉãÃÈ@@@@@@@@";
        String cadena = "ñâæÃÈÄóöó";
        System.out.println(Convert(cadena,"CP1047","ISO-8859-1"));
        cadena = "1SWCHD363";
        System.out.println(Convert(cadena,"ISO-8859-1","CP1047"));

    }

    public static String Convert (String strToConvert,String in, String out){
       try {

        Charset charset_in = Charset.forName(out);
        Charset charset_out = Charset.forName(in);

        CharsetDecoder decoder = charset_out.newDecoder();

        CharsetEncoder encoder = charset_in.newEncoder();

        CharBuffer uCharBuffer = CharBuffer.wrap(strToConvert);

        ByteBuffer bbuf = encoder.encode(uCharBuffer);

        CharBuffer cbuf = decoder.decode(bbuf);

        String s = cbuf.toString();

        //System.out.println("Original String is: " + s);
        return s;

    } catch (CharacterCodingException e) {

        //System.out.println("Character Coding Error: " + e.getMessage());
        return "";

    }


}

}

Добро пожаловать в SO! Объяснять свое решение не требуется, но с учетом хорошей практики, с хорошими побочными эффектами, которые люди учатся понимать и, следовательно, голосовать за ваш ответ. ;)

Markus W Mahlberg 02.04.2015 02:48

Возможно, как я, вы не использовали строго функцию JDBC (в моем случае запись в очередь данных), поэтому кодировка авто-магический к вам не применялась, поскольку мы общаемся через несколько API.

Моя проблема была похожа на проблему @scottyab, когда некоторые символы не отображались. В моем случае пример кода, на который я ссылался, работал отлично, но запись строки xml в очередь данных привела к замене [на £.

Как веб-разработчик, работающий с уже существующей базой данных с десятилетиями информации, У меня просто не было возможности «исправить» «неправильную конфигурацию»., как предлагает один другой комментатор.

Однако я смог увидеть, какой идентификатор набора кодированных символов, вероятно, использовал i, выполнив команду на 400 для отображения информации о поле файла в заведомо исправном файле: DSPFFD *LIB*/*FILE*.

Это дало мне хорошую информацию, включая конкретный набор CCSID: CCSID Identifier

После некоторого запрашиваемая информация о CCSID я наткнулся на страницу IBM для EBCDIC с ключевой информацией, напечатанной на странице (поскольку она имеет привычку исчезать):

Version 11.0.0 Extended Binary Coded Decimal Interchange Code (EBCDIC) is an encoding scheme that is typically used on zSeries (z/OS®) and iSeries (System i®).

И самое полезное:

Some example EBCDIC CCSIDs are 37, 500, and 1047.

Поскольку я уже сказал узнал из самого этого вопроса, что Cp1047 - еще один хороший набор символов, который стоит попробовать (на этот раз символ £ превратился в букву «Y» с акцентом), я попробовал Cp37, чтобы увидеть, что такого набора символов не существует, но попробовал Cp037 и получил правильную кодировку.

Похоже, ключ заключается в том, чтобы найти, какой Идентификатор кодированного набора символов (CCSID) используется в вашей системе, и убедиться, что ваш экземпляр jt400 - который в противном случае работает безупречно - соответствует на 100% кодировке, установленной на as400, в моем случае путь до моей жизни и десятилетий бизнес-логика назад.

Я делаю код, который легко преобразует типы данных.

public class Converter{

    public static void main(String[] args) {

        Charset charsetEBCDIC = Charset.forName("CP037");
        Charset charsetACSII = Charset.forName("US-ASCII");

        String ebcdic = "(((((((";
        System.out.println("String EBCDIC: " + ebcdic);
        System.out.println("String converted to ASCII: " + convertTO(ebcdic, charsetEBCDIC, charsetACSII));

        String ascII = "MMMMMM";
        System.out.println("String ASCII: " + ascII);
        System.out.println("String converted to EBCDIC: " + convertTO(ascII, charsetACSII, charsetEBCDIC));
    }

    public static String convertTO(String dados, Charset encondingFrom, Charset encondingTo) {
        return new String(dados.getBytes(encondingFrom), encondingTo);
    }
}

Я хочу добавить к тому, что сказали Квеббл и Шон С. Для этого я могу использовать JTOpen.

Мне нужно было записать в поле, которое было 6 0P (6 байтов, ничего после десятичной дроби, упаковано). Это десятичное число (11,0) для тех из вас, кто не разбирается в DDM.

    AS400PackedDecimal convertedCustId = new AS400PackedDecimal(11, 0);
    byte[] packedCust = convertedCustId.toBytes((int) custId);

    String packedCustStr = new String(packedCust, "Cp037");

    StringBuilder jcommData = new StringBuilder();
    jcommData.append(String.format("%6s", packedCustStr));

Да, я использовал упомянутую библиотеку KWebble. Глядя на DSPPFD, о котором упоминал Шон С., я обнаружил, что таблица использует CCSID 37. Это сработало.

Первоначально я пробовал использовать Cp1047, согласно предложению Алана Крюгера. Казалось, сработало. К сожалению, если мой custId заканчивался 5, данные, отображаемые в файл, были B0 вместо 5F. Изменение на Cp037 исправило это.

Другие вопросы по теме