关于 java 位运算
这段代码中和0x0ff与运算是什么意思? 获取length的原理是什么?
其中对象in如下
// read and check header
int type = in.read() & 0x0ff;
int identifier = in.read() & 0x0ff;
int length = (in.read() & 0x0ff) << 8 | (in.read() & 0x0ff);
所有的代码
/**
Reads a Radius packet from the given input stream and
creates an appropiate RadiusPacket descendant object.
Reads in all attributes and returns the object.
Decodes the encrypted fields and attributes of the packet.
@param dictionary dictionary to use for attributes
@param sharedSecret shared secret to be used to decode this packet
@param request Radius request packet if this is a response packet to be
decoded, null if this is a request packet to be decoded
@return new RadiusPacket object
@exception IOException if an IO error occurred
@exception RadiusException if the Radius packet is malformed
*/
static RadiusPacket decodePacket(Dictionary dictionary, InputStream in, String sharedSecret, RadiusPacket request)
IOException, RadiusException {
// check shared secret if (sharedSecret == null || sharedSecret.length() == 0) throw new RuntimeException("no shared secret has been set"); // check request authenticator if (request != null && request.getAuthenticator() == null) throw new RuntimeException("request authenticator not set"); // read and check header int type = in.read() & 0x0ff; int identifier = in.read() & 0x0ff; int length = (in.read() & 0x0ff) << 8 | (in.read() & 0x0ff); if (request != null && request.getPacketIdentifier() != identifier) throw new RadiusException("bad packet: invalid packet identifier (request: " + request.getPacketIdentifier() + ", response: " + identifier); if (length < RADIUS_HEADER_LENGTH) throw new RadiusException("bad packet: packet too short (" + length + " bytes)"); if (length > MAX_PACKET_LENGTH) throw new RadiusException("bad packet: packet too long (" + length + " bytes)"); // read rest of packet byte[] authenticator = new byte[16]; byte[] attributeData = new byte[length - RADIUS_HEADER_LENGTH]; in.read(authenticator); in.read(attributeData); // check and count attributes int pos = 0; int attributeCount = 0; while (pos < attributeData.length) { if (pos + 1 >= attributeData.length) throw new RadiusException("bad packet: attribute length mismatch"); int attributeLength = attributeData[pos + 1] & 0x0ff; if (attributeLength < 2) throw new RadiusException("bad packet: invalid attribute length"); pos += attributeLength; attributeCount++; } if (pos != attributeData.length) throw new RadiusException("bad packet: attribute length mismatch"); // create RadiusPacket object; set properties RadiusPacket rp = createRadiusPacket(type); rp.setPacketType(type); rp.setPacketIdentifier(identifier); rp.authenticator = authenticator; // load attributes pos = 0; while (pos < attributeData.length) { int attributeType = attributeData[pos] & 0x0ff; int attributeLength = attributeData[pos + 1] & 0x0ff; RadiusAttribute a = RadiusAttribute.createRadiusAttribute(dictionary, -1, attributeType); a.readAttribute(attributeData, pos, attributeLength); rp.addAttribute(a); pos += attributeLength; } // request packet? if (request == null) { // decode attributes rp.decodeRequestAttributes(sharedSecret); rp.checkRequestAuthenticator(sharedSecret, length, attributeData); } else { // response packet: check authenticator rp.checkResponseAuthenticator(sharedSecret, length, attributeData, request.getAuthenticator()); } return rp;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
0x0ff 就是
一个数字和 0x0ff 进行与运算,则会把高8位置0,低8位保留。
回到你的程序中,通过这个函数猜测应该是解析的 RFC2866 报文:
报文格式:
根据格式, 0-7位是 CODE 信息,在你的函数中用 type 存储。(注意 type 的类型,是 int)
@brayden 提到了,
InputStream.read()
一个读一个 byte,正好是 8 位,所以,如果写byte type = in.read()
就正好了。但是 type 的类型是 int,因此我们需要处理一下。如果我们读入的是 5,那么当我们把他转换成 int 时,也应该是 5。那么需要在前面添加 0。
同理,读报文的 8-15位。
length
的值比较难读取,因为它一共16位,而in.read()
每次只能读8个字节,那么就需要读取两次,然后拼凑。方法是,先读8位,然后左移,再读8位。java里InputStream.read()一个读一个byte, 但是返回一个int, 四字节; 但实际上有用的只是最后的那个byte. 所以需要每次in.read() & 0x0ff;
具体到这段代码,
读第一个byte到一个int型, 赋值给type;
读第二个byte到一个int型, 赋值给identifier;
读第三个byte, 第四个byte, 第三个字节左移8位, 和第四个字节拼接起来, 赋值给length.