Как достичь php ^ в java [duplicate]

Ссылка NullReferenceException или Object, не установленная на экземпляр объекта, возникает, когда объект класса, который вы пытаетесь использовать, не создается. Например:

Предположим, что у вас есть класс с именем Student.

public class Student
{
    private string FirstName;
    private string LastName;
    public string GetFullName()
    {
        return FirstName + LastName;
    }
}

Теперь рассмотрим другой класс, в котором вы пытаетесь получить полное имя учащегося.

public class StudentInfo
{      
    public string GetStudentName()
    {
        Student s;
        string fullname = s.GetFullName();
        return fullname;
    }        
}

Как видно из вышеприведенного кода, оператор Student s - объявляет только переменную типа Student, обратите внимание, что класс Student не создается в этой точке. Следовательно, когда выполняется выполнение инструкции s.GetFullName (), она выкинет исключение NullReferenceException.

45
задан yasitha 26 February 2011 в 12:28
поделиться

7 ответов

Предполагая (!) строки одинаковой длины, почему бы преобразовать строки в байтовые массивы , а затем XOR байты. Результирующие байт-массивы могут иметь разную длину также в зависимости от вашего кодирования (например, UTF8 будет расширяться до разных длин байтов для разных символов).

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

3
ответ дан Community 1 September 2018 в 06:47
поделиться

функция abs - это когда строки имеют одинаковую длину, поэтому нога результата будет такой же, как и минимальная длина двух строк a и b

public String xor(String a, String b){
    StringBuilder sb = new StringBuilder();
    for(int k=0; k < a.length(); k++)
       sb.append((a.charAt(k) ^ b.charAt(k + (Math.abs(a.length() - b.length()))))) ;
       return sb.toString();
}
1
ответ дан dit 1 September 2018 в 06:47
поделиться

Это решение совместимо с Android (я тестировал и использовал его сам). Благодаря @ user467257, решение которого я адаптировал это.

import android.util.Base64;

public class StringXORer {

public String encode(String s, String key) {
    return new String(Base64.encode(xorWithKey(s.getBytes(), key.getBytes()), Base64.DEFAULT));
}

public String decode(String s, String key) {
    return new String(xorWithKey(base64Decode(s), key.getBytes()));
}

private byte[] xorWithKey(byte[] a, byte[] key) {
    byte[] out = new byte[a.length];
    for (int i = 0; i < a.length; i++) {
        out[i] = (byte) (a[i] ^ key[i%key.length]);
    }
    return out;
}

private byte[] base64Decode(String s) {
    return Base64.decode(s,Base64.DEFAULT);
}

private String base64Encode(byte[] bytes) {
    return new String(Base64.encode(bytes,Base64.DEFAULT));

}
}
1
ответ дан nemesisfixx 1 September 2018 в 06:47
поделиться

Обратите внимание:

Java char соответствует кодовому модулю UTF-16, а в некоторых случаях два последовательных char s (так называемая суррогатная пара ) необходимы для одного реального символа Unicode (codepoint).

XORing две допустимые последовательности UTF-16 (например, строки Java char на char или байты по байтам после кодирования в UTF-16) не обязательно дает вам другую действительную строку UTF-16 - в результате у вас могут быть непарные суррогаты. (Это все равно будет прекрасно использоваться Java String, только методы, связанные с кодеком, могут запутаться, а те, которые преобразуются в другие кодировки для вывода и аналогичные.)

То же самое верно, если вы сначала конвертируете ваши строки в UTF-8, а затем XOR эти байты - здесь вы, скорее всего, закончите с байтовой последовательностью, которая недействительна UTF-8, если ваши строки не были и чистыми ASCII-строками.

Even если вы попытаетесь сделать это правильно и выполните итерацию по вашим двум строкам по кодовым точкам и попробуйте XOR для кодовых точек, вы можете в конечном итоге с кодовыми точками за пределами допустимого диапазона (например, U+FFFFF (плоскость 15) XOR U+10000 (плоскость 16) = U+1FFFFF (который был бы последним символом плоскости 31), который был бы выше диапазона существующих кодовых точек. И вы также могли бы сделать это с помощью кодовых точек, зарезервированных для суррогатов (= недействительных).

Если ваши строки содержат только символы 128, 256, 512, 1024, 2048, 4096, 8192, 16384 или 32768, тогда строковые строки XORed будут находиться в том же диапазоне, и thu безусловно, не содержат суррогатов. В первых двух случаях вы также можете кодировать свою строку как ASCII или Latin-1, соответственно, и иметь тот же XOR-результат для байтов. (Вы все еще можете получить контрольные символы, что может быть проблемой для вас.)


Что я, наконец, говорю здесь: не ожидайте, что результат шифрования строк будет действительным string снова - вместо этого просто сохраните и передайте его как byte[] (или поток байтов). (И да, конвертировать в UTF-8 до шифрования и из UTF-8 после дешифрования).

16
ответ дан Paŭlo Ebermann 1 September 2018 в 06:47
поделиться

Примечание: это работает только для низких символов, то есть ниже 0x8000. Это работает для всех символов ASCII.

Я бы сделал XOR каждый charAt () для создания новой строки. Как

String s, key;

StringBuilder sb = new StringBuilder();
for(int i = 0; i < s.length(); i++)
    sb.append((char)(s.charAt(i) ^ key.charAt(i % key.length())));
String result = sb.toString();

В ответ на комментарий @ user467257

Если ваш ввод / вывод - utf-8, а вы xor «a» и «æ», вы остаетесь с недопустимой строкой utf-8, состоящей из одного символа (десятичный 135, символ продолжения).

Это значения char, которые являются xor'ed, но байтовые значения, и это создает символ, который является кодировкой UTF-8.

public static void main(String... args) throws UnsupportedEncodingException {
    char ch1 = 'a';
    char ch2 = 'æ';
    char ch3 = (char) (ch1 ^ ch2);
    System.out.println((int) ch3 + " UTF-8 encoded is " + Arrays.toString(String.valueOf(ch3).getBytes("UTF-8")));
}

печатает

135 UTF-8 encoded is [-62, -121]
27
ответ дан Peter Lawrey 1 September 2018 в 06:47
поделиться

Вы хотите что-то вроде этого:

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
import java.io.IOException;

public class StringXORer {

    public String encode(String s, String key) {
        return base64Encode(xorWithKey(s.getBytes(), key.getBytes()));
    }

    public String decode(String s, String key) {
        return new String(xorWithKey(base64Decode(s), key.getBytes()));
    }

    private byte[] xorWithKey(byte[] a, byte[] key) {
        byte[] out = new byte[a.length];
        for (int i = 0; i < a.length; i++) {
            out[i] = (byte) (a[i] ^ key[i%key.length]);
        }
        return out;
    }

    private byte[] base64Decode(String s) {
        try {
            BASE64Decoder d = new BASE64Decoder();
            return d.decodeBuffer(s);
        } catch (IOException e) {throw new RuntimeException(e);}
    }

    private String base64Encode(byte[] bytes) {
        BASE64Encoder enc = new BASE64Encoder();
        return enc.encode(bytes).replaceAll("\\s", "");

    }
}

Кодировка base64 выполняется, поскольку xor'ing байтов строки может не возвращать верные байты для строки.

47
ответ дан user467257 1 September 2018 в 06:47
поделиться

Это код, который я использую:

private static byte[] xor(final byte[] input, final byte[] secret) {
    final byte[] output = new byte[input.length];
    if (secret.length == 0) {
        throw new IllegalArgumentException("empty security key");
    }
    int spos = 0;
    for (int pos = 0; pos < input.length; ++pos) {
        output[pos] = (byte) (input[pos] ^ secret[spos]);
        ++spos;
        if (spos >= secret.length) {
            spos = 0;
        }
    }
    return output;
}
3
ответ дан yegor256 1 September 2018 в 06:47
поделиться
Другие вопросы по тегам:

Похожие вопросы: