Преобразование байта в строку и наоборот на разных платформах

У меня есть два приложения, работающих на разных серверах, одно с JDK 1.6, а другое с JRockit.

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

Нижеприведенная программа может использоваться для маскирования и демаскирования, и на обоих серверах работает одна и та же программа.

Я пробовал использовать формат кодировки "ISO-8859-1" на обоих серверах, но это мне не помогло. При декодировании значения программа дает сбой и выдает мусор. Раньше, когда эти два приложения размещались на одном сервере, они работали и не имели проблем.

Ниже программа...помогите пожалуйста...

    String prefix = "dEncrypt";

    if(null==value||value.length()<1){
        return value;
    }
    else{
        byte[] input = null;
        try {
            value = new String(value);
            //String value1 = new String(value,"UTF-8");
            input = URLDecoder.decode(value).getBytes("ISO-8859-1");
            for(int i =0 ;i<input.length ; i++)
                System.out.println("input=" + input[i]);
        } catch (Exception e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }

        byte[] key = null;
        try {
            key = "123456789123456789123456789".getBytes("ISO-8859-1");
            for(int i =0 ;i<key.length ; i++)
                System.out.println("key=" + key[i]);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        byte[] state = new byte[256];
        int x, y;

        for( int i = 0; i < state.length; i++ ) {
            state[i] = (byte) i;
            }
        x = 0;
        for( int i = 0; i < state.length; i++ ) {
            x = (x + key[i % key.length] + state[i]) & 0xFF;
            //System.out.println("x=" + x);
            byte swap = state[i];
            state[i] = state[x];
            state[x] = swap;
            }
        x = 0;y=0;
        byte[] output = new byte[input.length];
        for( int i = 0; i < input.length; i++ ) {
        x = (x + 1) % 256;
        y = (state[x] + y) & 0xFF;
        byte swap = state[x];
        state[x] = state[y];
        state[y] = swap;
        byte r = state[(state[x] + state[y]) & 0xFF];
        output[i] = (byte) (input[i] ^ r);
        System.out.println("output=" + output[i]);
        }

        try {
            //System.out.println(" New string " +URLEncoder.encode(new String(output,"UTF-16") ));
            byte [] enc = Charset.forName("ISO-8859-1").encode(new String(output)).array();
            System.out.println(Charset.isSupported("base64"));
            //Charset.
            System.out.println(new String(enc));
            System.out.println("URLEncoded1=" + URLEncoder.encode(new String(enc)));
            System.out.println("URLEncoded2=" + URLEncoder.encode(new String(output,"ISO-8859-1")));
            return URLEncoder.encode(new String(output,"ISO-8859-1"));
        } catch (UnsupportedEncodingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return URLEncoder.encode(new String(output));
    }

person Indranil    schedule 23.01.2014    source источник
comment
Оператор типа value = new String(value); вообще не имеет смысла, он фактически ничего не делает, если value уже является String.   -  person Jesper    schedule 23.01.2014
comment
Да, Джеспер, наверное, я пытался что-то еще... и забыл удалить...   -  person Indranil    schedule 23.01.2014


Ответы (2)


В общем, всегда используйте getBytes и new String с параметром кодирования. В противном случае используется кодировка платформы по умолчанию. А с двумя компьютерами...

Примечание. value = new String(value); можно удалить, так как объекты String являются (почти) неизменяемыми.

byte [] enc = Charset.forName("ISO-8859-1").encode(new String(output)).array();

Должно быть (для совместимости с getBytes("ISO-8859-1")):

byte [] enc = Charset.forName("ISO-8859-1").encode(
        new String(output, "ISO-8859-1")).array();

что сводится к:

byte[] enc = output; // Or: Arrays.copyOf(output, output.length);

И, следовательно

new String(enc)

должно быть:

new String(enc, "ISO-8859-1")

В общем ничего особо не делается.

person Joop Eggen    schedule 23.01.2014
comment
Я пытался увидеть, как он печатает с несколькими вариантами... удивительно, что это было по-другому... - person Indranil; 23.01.2014

Я не совсем уверен, чего вы пытаетесь достичь, но если вы просто хотите отправить байты (двоичные данные) по текстовой ссылке (http), вы можете просто использовать вместо этого UUEncode (или Base64, или yEnc).

person Mikkel Løkke    schedule 23.01.2014