Java:如何使用字节创建包?

时间:2011-06-06 17:31:12

标签: java encryption header

我正在一个项目中工作,我需要读取一些值并通过套接字连接发送。 这是我必须创建的包的格式: enter image description here

我必须阅读这些值(我不知道每个值,int或字符串等必须是什么类型的王): type:操作类型(如何只获得4位?) reserverd:我将用0填充 来源:谁在发送消息 接收者:谁将收到消息 算法:使用哪种算法来加密消息 padding:在加密算法中使用它 mode:要加密的模式

我必须读取这些值并创建这个必须只有7个字节的包。

我该怎么做?

我认为必须是这样的事情:

byte[] r = new byte[]{
               type+reserverd, 
               origin_1_byte, origin_2_byte, 
               receiver_1_byte, receiver_2_byte, 
               algorithm+padding, 
               mode};

更新:

ByteBuffer buffer = ByteBuffer.allocate(100);
// read data into buffer
buffer.rewind();
buffer.order(ByteOrder.LITTLE_ENDIAN);
// 0xf and co mask off sign extension -> handle byte as unsigned
int type = (buffer.get() >> 4) & 0xf; // 15 in decimal

buffer.rewind();
buffer.put((byte)(type << 4));
System.out.println("type = " + type);


output : 0 (why ?)

有什么想法吗?

5 个答案:

答案 0 :(得分:2)

只需使用ByteBuffer和nio包。通过这种方式,您可以轻松地从网络中读取数据,而不必担心Endianess(这很重要!如果您使用流,您几乎必须自己实施转换 - 尽管这可能是一个很好的练习)。不要忘记将缓冲区字节顺序设置为正确的值。我们在内部使用int,因为a)所有数学运算无论如何都返回int。b)你能够将值作为无符号处理。

    ByteBuffer buffer = ByteBuffer.allocate(100);
    // read data into buffer
    buffer.rewind();
    buffer.order(ByteOrder.LITTLE_ENDIAN);
            // 0xf and co mask off sign extension -> handle byte as unsigned
    int type = (buffer.get() >> 4) & 0xf; 
    int origin = buffer.getShort() & 0xffff;
    int receiver = buffer.getShort() & 0xffff;
    // and so on

将数据写回来你几乎反过来了:

    ByteBuffer buffer = ByteBuffer.allocate(100);
    buffer.rewind();
    buffer.put((byte)(type << 4));
    buffer.putShort((short)origin);
    // and so on

编辑: 通常,您可以从网络通道直接将数据读入ByteBuffer并使用Java NIO包。快速教程是here。但是既然你已经有了Socket,我们会让它变得更容易一些。请注意,我忽略了所有错误检查的简单性。使用OutputStream和WritableByteChannel(使用write)可以在另一个方向上工作。

InputStream is = socket.getInputStream();
ReadableByteChannel source = Channels.newChannel(istream);
ByteBuffer buffer = ByteBuffer.allocateDirect(headerSize);
source.read(buffer);
// now header is in buffer and can be used as seen above. 

答案 1 :(得分:0)

查看ByteBuffer

还要研究位操作,例如“移位”。如果您需要将3存储到type而将7存储到reserved,那么您只需将它们存储为8位byte即可。

byte typeReserved = (3 << 4) | 7;

想要获得价值吗?

byte type = (typeReserved >> 4) & 0xF;
byte reserved = typeReserved & 0xF;

答案 2 :(得分:0)

我在使用字节时遇到了同样的问题,我也发现Java中没有“无符号字节”,所以如果我是正确的话,字节值只会从-128到127。我被限制使用短路,好像它们是字节,所以我可以使用高达255的值。

我确信有一条出路,但当时我没有足够的时间来弄明白

答案 3 :(得分:0)

你使用位移(使用<<)和按位(使用|

new byte[]{
           type<<4|reserverd, 
           origin_1_byte, origin_2_byte, 
           receiver_1_byte, receiver_2_byte, 
           algorithm<<4 | padding, 
           mode};

要提取它们,你需要掩码和移位(例如buff[0]&0xf0)>>>4将提取类型)

答案 4 :(得分:0)

ByteBuffer,如其他答案所示,或DataOutputStream。