2014-09-12 4 views
2

я получаю ответ от сервера в виде строки, какКак получить побайтно из байтового массива

V1YYZZ0x0000010x0D0x00112050x0C152031962061900x0D410240x0E152031962061900x0F410240x1021TATADOCOMOINTERNET101 

Тогда я преобразуя его, чтобы массив байтов, потому что мне нужно получить значение из этого побайтно.

Я пытался использовать

Arrays.copyOfRange(original, 
         from , to); 

, но она работает на указательный основе не на основе байта.

Я также пробовал следующее решение, но оно также обрезало String (если я использую строку вместо байта []) по длине.

public static String truncateWhenUTF8(String s, int maxBytes) { 
    int b = 0; 
    for (int i = 0; i < s.length(); i++) { 
     char c = s.charAt(i); 

     // ranges from http://en.wikipedia.org/wiki/UTF-8 
     int skip = 0; 
     int more; 
     if (c <= 0x007f) { 
      more = 1; 
     } else if (c <= 0x07FF) { 
      more = 2; 
     } else if (c <= 0xd7ff) { 
      more = 3; 
     } else if (c <= 0xDFFF) { 
      // surrogate area, consume next char as well 
      more = 4; 
      skip = 1; 
     } else { 
      more = 3; 
     } 

     if (b + more > maxBytes) { 
      return s.substring(0, i); 
     } 
     b += more; 
     i += skip; 
    } 
    return s; 
} 

Я знаю, как вычислить строку длиной байт, но он дает только полную длину строки в байтах, как

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

enter image description here

Выше кодов и параметров является лишь примером. Мне нужно получить byte by byte из массива string/byte.

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

Пожалуйста, дайте мне любую ссылку или подсказку.

+0

Используйте подстроку, так как формат/длина известны. Если вы используете регулярное выражение, рассмотрите * match *, а не split. Итак, во всяком случае .. какая проблема * есть? Кроме того, поскольку ответ представляет собой строку, скорее всего, лучше подумать о символах, а не о байтах. – user2864740

+0

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

+0

На самом деле нам нужна разделительная строка с использованием байта только потому, что у меня есть только длина байта для этого параметра ... –

ответ

2

Чтобы определить, что равно одному байту в строке, нетривиально. Ваша строка содержит байты в шестнадцатеричной текстовой форме: 0x0D (один байт, равный 13), но также содержит значения в качестве подстрок. Например, 1024 можно интерпретировать как целое число, которое в этом случае вписывается в 2 байта, но может также интерпретироваться как текст, составленный из 4 символов, всего 8 байт.

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

String message = "V1YYZZ0x0000010x0D0x00112050x0C152031962061900x0D41024"+ 
    "0x0E152031962061900x0F410240x1021TATADOCOMOINTERNET101"; 
String regex = "(0)(x)(\\w\\w)"; 
String[] parts = message.split(regex); 
Log.d(TAG,"HEADER = "+parts[0]); 
for (int i=1; i<parts.length; i++) { 
    String s = parts[i]; 
    // Only process if it has length > 0 
    if (s.length()>0) { 
     String len = "", val = ""; 
     // String s is now in format LVVVV where L is the length, V is the value 
     if (s.length() < 11) { 
      // 1 character indicates length, up to 9 contains value 
      len = s.substring(0, 1); 
      val = s.substring(1); 
     } else if (s.length() > 10) { 
      // 2 characters indicate length, up to 99 contains value 
      len = s.substring(0, 2); 
      val = s.substring(2); 
     } else if (s.length() > 101) { 
      // 3 characters indicate length, up to 999 contains value 
      len = s.substring(0, 3); 
      val = s.substring(3); 
     } 
     Log.d(TAG, "Length: " + len + " Value: " + val); 
    } 
} 

Это производит следующий вывод:

D/Activity: HEADER = V1YYZZ 
D/Activity: Length: 0 Value: 001 
D/Activity: Length: 1 Value: 1205 
D/Activity: Length: 15 Value: 203196206190 
D/Activity: Length: 4 Value: 1024 
D/Activity: Length: 15 Value: 203196206190 
D/Activity: Length: 4 Value: 1024 
D/Activity: Length: 21 Value: TATADOCOMOINTERNET101 

Тогда вы можете проверьте пакеты (первые два пакета в заголовке не нужны), преобразуйте строки в любое удобное для вас (например, Integer.parseInt(val))

Если вы ex Простая структура заголовка (V1YYZZ0x0000010x0D0x0011205), я могу улучшить свой ответ, чтобы найти количество сообщений.

+0

@SandipArmalPatil Можете ли вы объяснить заголовок? Любой прогресс в вашей проблеме? – Gyebro

+0

«Варам-код» (вероятно, предполагается, что это «код param») (первая часть выделенного пакета 0x) указывает на назначение и кодировку значения параметра. Это помогло бы, если бы ваш тестовый результат включал это. – Makyen

1

Я думаю, что это выполнимо с помощью сканера

import java.util.Scanner; 

public class Library { 

public static void main(String[] args) { 
    String s = "V1YYZZ0x0000010x0D0x001120" 
     + "50x0C152031962061900x0D410240x0E152031962061900x0F410240x1" 
     + "021TATADOCOMOINTERNET101"; 

    // Skip first 9? bytes. I'm not sure how you define them 
    // so I just assumed it is 26 chars long. 
    s = s.substring(26, s.length()); 
    System.out.println(s); 
    Scanner scanner = new Scanner(s); 
    // Use byte as delimiter i.e. 0xDC, 0x00 
    // Maybe you should use smth like 0x[\\da-fA-F]{2} 
    // And if you want to know that byte, you should use 
    // just 0x and get first 2 chars later 
    scanner.useDelimiter("0x\\w{2}"); 
    // Easily extracted 
    int numberOfParams = scanner.nextInt(); 
    for (int i = 0; i < numberOfParams; i++) { 
     String extracted = scanner.next(); 
     // Length of message 
     int l = extracted.length(); 
     boolean c = getLength(l) == getLength(l - getLength(l)); 
     l -= getLength(l); 
     l = c ? l : l-1; 

     System.out.println("length=" 
       + extracted.substring(0, extracted.length()-l)); 
     System.out.println("message=" 
       + extracted.substring(extracted.length()-l, extracted.length())); 
    } 
    // close the scanner 
    scanner.close(); 
} 
// Counting digits assuming number is decimal 
private static int getLength(int l) { 
    int length = (int) (Math.log10(l) + 1); 
    System.out.println("counted length = " + length); 
    return length; 
} 
} 

Нам определенно нужно больше информации о правилах, как формируется строка. И что именно вам нужно делать. Этот код может быть достаточно хорошим. И без комментариев это действительно коротко и просто.

0

Уверен, что мне не хватает чего-то очевидного ...

String.getBytes(); 

И если вы хотите, чтобы обработать его, чтобы принимать определенные объекты из массива, просто обернуть с помощью

ByteBuffer.wrap(); 

результатом является то, вдоль линий:

String s = "OUTPUT FROM SERVER"; 
byte[] bytes = s.getBytes(); 
ByteBuffer bb = ByteBuffer.wrap(bytes); 

Что я пропустил из первоначального вопроса? :/

2

Это не ответ на доступ к байту байта массива байтом, но является ответом на ситуацию, в которой вы находите себя.

Ваши объяснения и описание имеют смутное представление о том, что именно вы действительно получаете с сервера (например, довольно сложно представить «V1YYZZ0x0000010x0D0x001120» как поле с 9 байтами (обратите внимание, что это, вероятно, заканчивается на 2, а не 0)). Альтернативно, вы используете неправильный метод для его получения с сервера или не получаете его как предполагаемый тип данных.

Ваш код указывает, что вы считаете, что то, что вы получаете, является строкой UTF8. Данные, показанные в вашем вопросе, как представляется, не указывают на то, что они предназначены для использования в этом формате.

Помните, что когда-либо делал что-то вроде этого, чтобы какой-то другой программист должен был создать структуру для данных, которые вы видите. Они должны были определить его где-то с намерением, чтобы он мог быть расшифрован их предполагаемыми получателями. Если нет других соображений (безопасность, минимальная пропускная способность и т. Д.), Такие форматы обычно определяются способом, который легко кодировать и декодировать.

Существование множества «0x» -ASCII-кодированных шестнадцатеричных чисел - особенно одиночный байт, представляющий параметр (называемый «varam» на графике) - сильно подразумевает, что эти данные должны были интерпретироваться как ASCII закодированная строка. Хотя это может быть и не так, его следует учитывать при рассмотрении проблемы с большей точки зрения.

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

Все это указывает на то, что реальная проблема существует в области, для которой вы предоставили нам никакой информации.

Шаг назад: Подумайте о таких вещах, как: Как вы получать это от сервера (что функция/интерфейс)?
В запросе, запрашивающем информацию с сервера, есть способ указать тип кодировки be bytes, строку ASCII или какой-либо другой формат, с которым легче справиться, чем UTF8? Как минимум, очевидно, что данные не предназначены для обработки в виде строки UTF8. Должен быть способ получить его без его преобразования в UTF8.

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

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

+0

И может быть способ запросить сервер для ответа с более стандартным форматом, таким как JSON, XML и т. Д. –

Смежные вопросы