Ошибка Java и подстроки - PullRequest
       25

Ошибка Java и подстроки

1 голос
/ 31 января 2012

Я реализую метод шифрования с помощью ключа, и я сделал вызов, подобный этому:

Crypto c = new Crypto("mysecretkey");
String enc = c.encrypt("mytext");

Но я получаю исключение

"Ошибка криптографического шифрования:Индекс строки вне диапазона: -1 "

в этой части:

String sKeyChar = getKey().substring((i % getKey().length()) - 1, 1);

И я не знаю, что я делаю неправильно, потому что я сделал то же самое в PHPи работает хорошо.Может быть, это просто, но я застрял, это мой метод:

public String encrypt(String sData) {
        String sEncrypted = null;
        try {
            String sResult = null;
            for (int i = 0; i < sData.length(); i++) {
                String sChar = sData.substring(i, 1);
                String sKeyChar = getKey().substring((i % getKey().length()) - 1, 1);
                char c = (char) (ord(sChar) - ord(sKeyChar));
                String sPart = (new StringBuffer().append(c)).toString();
                sResult += sPart;
            }
            byte[] sResultBuff = sResult.getBytes("UTF-8");
            sEncrypted = Base64.encode(sResultBuff);
        } catch (Exception e) {
            System.out.println("crypto encrypt error: " + e.getMessage());
            sEncrypted = null;
        }
        return sEncrypted;
    }

Другой необходимый метод:

public int ord(String sChar) {
    int ascii_code = 0;
    try {
        ascii_code = String.valueOf(sChar.charAt(0)).codePointAt(0);
    } catch (Exception e) {
        System.out.println("crypto ord error: " + e.getMessage());
        ascii_code = 0;
    }
    return ascii_code;
}

PHP эквивалентный метод:

function encrypt($sData, $sKey='mysecretkey'){ 
    $sResult = ''; 
    for($i=0;$i<strlen($sData);$i++){ 
        $sChar    = substr($sData, $i, 1); 
        $sKeyChar = substr($sKey, ($i % strlen($sKey)) - 1, 1); 
        $sChar    = chr(ord($sChar) + ord($sKeyChar)); 
        $sResult .= $sChar; 
    } 
    return encode_base64($sResult); 
} 

Спасибо!

Ответы [ 3 ]

2 голосов
/ 31 января 2012

Ваш расчет неверен: (i % getKey().length()) - 1 приведет к -1 для i = 0, то есть прямо в первой итерации.Таким образом, вы пытаетесь передать -1 в метод substring(...), что недопустимо.

Также обратите внимание, что если данные длиннее ключа, i % getKey().length() приведет к 0 для каждого кратного ключадлина.

Кроме того, параметры для substring(...) не являются index и length, но startIndex (включительно) и endIndex (исключение).Таким образом, String sChar = sData.substring(i, 1); сгенерирует исключение, как только i достигнет 2 (и выше), и не будет ничего возвращать для i = 1.

Возможно, вы захотите использовать charAt(i) вместо (и getKey().charAt(i % getKey().length()) вследующая строка).Обратите внимание, что при этом возвращается один символ, что делает метод ord(...) устаревшим.

В качестве примечания: String.valueOf(sChar.charAt(0)).codePointAt(0) эквивалентно sChar.codePointAt(0).

Еще одно примечание:

char c = (char) (ord(sChar) - ord(sKeyChar));
String sPart = (new StringBuffer().append(c)).toString();
sResult += sPart; 

можно упростить до

char c = (char) (ord(sChar) - ord(sKeyChar));
sResult += c; //you could also merge those two lines
1 голос
/ 31 января 2012

Вы видите разницу между PHP и Java, потому что PHP substr понимает отрицательные числа, а Java substring - нет: выдает исключение.

В PHP передача отрицательного значения 1 в substr означает «получить мне последний символ», но в Java вам нужно передать индекс последнего символа (т. Е. str.length()-1) для достижения того же эффекта.

Если это не ошибка и именно этого эффекта вы хотели достичь, вы можете решить эту проблему с помощью условия if:

int pos = (i % getKey().length()) - 1;
if (pos == -1) {
    pos = getKey().length() - 1;
}
// EDIT: Second argument needs to be pos+1, not 1. Thomas pointed out this error
String sKeyChar = getKey().substring(pos, pos+1);

РЕДАКТИРОВАТЬ Как правильно заметил Томас, другая разница между PHP-версией substr и Java substring заключается в том, что они обрабатывают второй аргумент: PHP считает, что его длина; Java считает, что это индекс последнего символа плюс один.

0 голосов
/ 31 января 2012

Как уже отмечалось, substr в PHP имеет другую семантику, чем в Java. В PHP это

string substr ( string $string , int $start [, int $length ] )
и он также принимает отрицательные числа (которые изменяют его поведение),


в то время как в Java это определяется как:

 String     substring(int beginIndex, int endIndex) 

и создает исключение для отрицательных чисел или, если beginIndex больше endIndex. Подводя итог, они разные, и вам нужно это компенсировать.

...