2013-04-10 3 views
1

У меня есть строка в следующем формате: ----- BEGIN MESSAGE -----, за которым следует зашифрованный ключ сеанса переменной длины, за которым следует новая строка, за которым следует зашифрованное сообщение , за которым следует новая линия, а затем цифровая подпись, а затем ----- ЗАВЕРШЕНИЕ СООБЩЕНИЯ -----.Анализ текста из строки Java

-----BEGIN MESSAGE----- 
SNyeWtz8QD8AKdioMG11wu7U6gG2wD9tekvVrx6VYW+6oJj4Wl8NE+7i5MHbu4Au 
+vN1Z886lOWka7ekgPF8N7t9MpiFo2pBPHuFcOsaY5ETYuEyk5gaX7BYP7qT6wKG 
BRILmX6DblWqGxG2tKs/AdcHDqQ5QBXrP03uhN68wgo= 

U2FsdGVkX18gtpQSqyH4H5242SZzcZrb0oH7FWw7/MSCxo7h7BVaesZV2N38sr9y 

kVr+wabiNn4RfAB4nNi9gAZHQLok4uxRMALGF2kZk2zpVNPQo6jcdz85fy68gylX 
OCQIIdk8JPIwxzHfVvRZqNHDRADZRlNHUMYScjRPU+DB8avghYAVKMJhLgA/2Tdp 
a59uBMBg/yB1yqA5FivxPzOhq92Y4nZuP1R9/yGE9O8K 
-----END MESSAGE----- 

Что такое лучший способ разобрать три части информации (ключа сеанса, зашифрованного сообщения и цифровой подписи)?

Я пробовал использовать класс сканера, но я не понимаю, что использовать в качестве измерителя. Я также попытался использовать класс Pattern, но не смог понять этот метод. Спасибо!

+0

Я только что-то схожу. Вопрос в том, хотите ли вы, чтобы эти три части данных были в одном матче? С 3 группами захвата? Или в 3 отдельных матчах? – Suamere

+0

String.split ("\ n")? –

+0

Suamere, я хочу 3 отдельных матча. Jaynathan, я пробовал использовать «\ n» в качестве делиметра, но это не сработало, потому что за каждой строкой следует новая строка. Например, зашифрованный ключ сеанса имеет длину 3 строки, каждая строка - новая строка. Я даже пытался использовать «\ n \ n» в качестве делиметра, но это тоже не удалось. – Luke

ответ

1

Вы на самом деле имеют встроенные переводы строк в различных частях. Что их ограничивает пустой линия — две строки в строке. Я предполагаю, что вы хотите, чтобы каждая часть была удалена. Я бы предложил подход грубой силы:

StringBuilder sb = new StringBuilder(); 
String[] parts = input.split("\\r?\\n\\r?\\n"); // should be 3 long 
// strip out header and newlines from session key 
String[] lines = parts[0].split("\\r?\\n"); 
for (int i = 1; i < lines.length; ++i) { // skip first line 
    sb.append(lines[i]); 
} 
parts[0] = sb.toString(); 
// strip out header and newlines from message 
sb.setLength(0); 
lines = parts[1].split("\\r?\\n"); 
for (int i = 0; i < lines.length; ++i) { 
    sb.append(lines[i]); 
} 
parts[1] = sb.toString(); 
// finally, deal with the signature 
sb.setLength(0); 
lines = parts[2].split("\\r?\\n"); 
for (int i = 0; i < lines.length - 1; ++i) { 
    sb.append(lines[i]); 
} 
parts[2] = sb.toString(); 

Не изящно, но ясно, что происходит.

Альтернативным подходом было бы использовать Scanner, чтобы читать каждую строку и решать, что с ней делать. Три строки — заголовок, трейлер и пустая строка — будут иметь специальную обработку и повлиять на обработку. В противном случае просто добавляйте каждую строку, когда вы читаете ее до StringBuffer.

+0

Я надеялся, что это будет способ решить это с помощью регулярного выражения, но ваш метод определенно работает. Спасибо! – Luke

+0

@ Andy - Вероятно, есть способ использовать регулярное выражение, но мне было слишком лениво работать. :) –

+0

Примечание для OP и Ted. В Regex лучший способ получить linebreaks - [\ r \ n] + Это означает, что любая комбинация чисел либо перевода строки, либо возврата каретки в любом порядке один или несколько раз. Это намного чище, чем \ r \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \. Но даже более чистым является \ s +, особенно в этом случае, когда в каждой строке нет пробелов, только пробелы между ними. – Suamere

0

newline?

И удалите -----BEGIN MESSAGE----- от первого значения и -----END MESSAGE----- от последнего значения.

+0

Согласен.Если вы просто имеете дело с одним сертификатом и есть три строки. Просто замените сообщение begin/end ничем, затем строка или regex split на \ s + (я не верю, что внутри каждой строки есть пробелы, только между строками. – Suamere

0
String[] parts = string.split("\r?\n"); 
sessionKey = parts[1]; 
encryptedMessage = parts[3]; 
digitalSignature = parts[5]; 

\r? позволяет Windows, EOLS (\r\n) или Unix EOLS (\n).

+2

Новые строки не всегда можно полагать быть \ r \ n. \ s + было бы идеальным с утверждением о том, что внутри каждой части нет пробелов. – Suamere

+0

Да, это лучше, чем редактирование, которое я сделал, @Suamere. –

+0

@Suamere - Каждая часть имеет в ней новые строки. строки _blank_. –

1

Право, удалите начало и конец, как сказал Сергий. Затем разделите Regex на «\ s +» , например. в .NET:

Regex.Split(Regex.Replace(strCert, "(?i)\s*-{5}(BEGIN|END)\sMESSAGE-{5}\s*", ""), "\s+") 

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

-----BEGIN MESSAGE----- 
SNyeWtz8QD8AKdioMG11wu7U6gG2wD9tekvVrx6VYW+6oJj4Wl8NE+7i5MHbu4Au+vN1Z886lOWka7ekgPF8N7t9MpiFo2pBPHuFcOsaY5ETYuEyk5gaX7BYP7qT6wKGBRILmX6DblWqGxG2tKs/AdcHDqQ5QBXrP03uhN68wgo= 

U2FsdGVkX18gtpQSqyH4H5242SZzcZrb0oH7FWw7/MSCxo7h7BVaesZV2N38sr9y 

kVr+wabiNn4RfAB4nNi9gAZHQLok4uxRMALGF2kZk2zpVNPQo6jcdz85fy68gylXOCQIIdk8JPIwxzHfVvRZqNHDRADZRlNHUMYScjRPU+DB8avghYAVKMJhLgA/2Tdpa59uBMBg/yB1yqA5FivxPzOhq92Y4nZuP1R9/yGE9O8K 
-----END MESSAGE----- 

Ya?

+0

Это будет разбиваться на каждый разрыв строки, включая те разрывы строк, встроенные в каждую часть текста. OP необходимо сначала отделить пустые строки (две последовательные последовательности терминаторов строк). Для надежности он должен работать для всех разновидности последовательностей терминаторов строк: '\ r \ n' (Windows, HTTP standard),' \ r' (Mac) или '\ n' (Unix). –

+0

Неверно. \ s + будет собирать одно или несколько пробелов как одно . Это означает, что разрывы строк и pos на этих «пустых» линиях. Поэтому, если Begin и End были удалены вручную, все, что осталось, - это коллекция из трех областей. \ s + будет работать для всех многообразий терминаторных последовательностей. Единственная причина \ s + может не работать, если одна из этих строк информации включает пробелы, которые, согласно правилам сертификатов, никогда не будут. Но если бы и на пустую строку не было бы пробела, [\ r \ n] + тоже было бы неплохо, но \ s + еще более «надежный» – Suamere

+0

Хорошо, что разрывы строк должны отсутствовать в сообщении cert, message , и подпись. Однако я не уверен, что это требование относится к сообщению. Также полезно указать, что '\ s +' будет устойчивым к пробелу в предположительно пустых строках между частями. –

0

Код:

public class MessageParser { 

    public static void main(String[] args) { 
     String message = 
     "-----BEGIN MESSAGE-----\n" + 
     "SNyeWtz8QD8AKdioMG11wu7U6gG2wD9tekvVrx6VYW+6oJj4Wl8NE+7i5MHbu4Au\n" + 
     "+vN1Z886lOWka7ekgPF8N7t9MoiFo2pBPHuFcOsaY5ETYuEyk5gaX7BYP7qT6wKG\n" + 
     "BRILmX6DblWqGxG2tKs/AdcHDqQ5QBXrP03uhN68wgo=\n" + 
     "\n" + 
     "U2FsdGVkX18gtpQSqyH4H5242gZzcZrb0oH7FWw7/MSCxo7h7BVaesZV2N38sr9y\n" + 
     "\n" + 
     "kVr+wabiNn4RfAB4nNi9gAZHQLok4uxRMALGF2kZk2zpVNPQo6jcdz85fy68gylX\n" + 
     "OCQIIdk8JPIwxzHfVvRZqNHDRFDZRlNHUMYScjRPU+DB8avghYAVKMJhLgA/2Tdp\n" + 
     "a59uBMBg/yB1yqA5FivxPzOhq92Y4nZuP1R9/yGE9O8K\n" + 
     "-----END MESSAGE-----\n"; 
     String[] lines = message.split("\n"); 
     int i = 1; 
     String sessionKey = ""; 
     String line = lines[i]; 
     while(i < lines.length && line.length() > 0) { 
     sessionKey += line; 
     line = lines[++i]; 
     } 
     String encryptedMessage = ""; 
     line = lines[++i]; 
     while(i < lines.length && line.length() > 0) { 
     encryptedMessage += line; 
     line = lines[++i]; 
     } 
     String digitalSignature = ""; 
     line = lines[++i]; 
     while(i < lines.length && ! line.equals("-----END MESSAGE-----")) { 
     digitalSignature += line; 
     line = lines[++i]; 
     } 
     System.out.println("sessionKey  : " + sessionKey); 
     System.out.println("encryptedMessage: " + encryptedMessage); 
     System.out.println("digitalSignature: " + digitalSignature); 
    } 
} 

Выходные:

sessionKey  : SNyeWtz8QD8AKdioMG11wu7U6gG2wD9tekvVrx6VYW+6oJj4Wl8NE+7i5MHbu4Au+vN1Z886lOWka7ekgPF8N7t9MoiFo2pBPHuFcOsaY5ETYuEyk5gaX7BYP7qT6wKGBRILmX6DblWqGxG2tKs/AdcHDqQ5QBXrP03uhN68wgo= 
encryptedMessage: U2FsdGVkX18gtpQSqyH4H5242gZzcZrb0oH7FWw7/MSCxo7h7BVaesZV2N38sr9y 
digitalSignature: kVr+wabiNn4RfAB4nNi9gAZHQLok4uxRMALGF2kZk2zpVNPQo6jcdz85fy68gylXOCQIIdk8JPIwxzHfVvRZqNHDRFDZRlNHUMYScjRPU+DB8avghYAVKMJhLgA/2Tdpa59uBMBg/yB1yqA5FivxPzOhq92Y4nZuP1R9/yGE9O8K 
+0

Вы вынудили \ n перейти к примеру, чтобы разобрать их. – Suamere