uint32无符号字节转为Java中的int

本文介绍了如何在Java中处理无符号字节流转为int,以及字节缓冲流的基础使用,包括ByteBuffer的分配、存储、读取和String与ByteBuffer之间的转换。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


前言

Java 中基本类型都是有符号数值,如果接收到了 C/C++ 处理的无符号数值字节流,将出现转码错误。


提示:以下是本篇文章正文内容,下面案例可供参考

一、无符号字节转为int

1.前置知识

在线进制转换:https://tool.oschina.net/hexconvert
之前在解析 webscoket 传输得二进制数据时,因为二进制数据传输的是 uint32 无符号整数,需要把有符号的字节转为正常的;
uint32 代表无符号整数,只能存正整数,在内存中占4个字节,byte[4],0到4294967295,Java中 int 为32位有符号整数,占4字节,-2147483648 到 2147483648。

2.无符号转int代码

public static long bytes2int(byte[] buf){
    long anUnsignedInt = 0;
    int firstByte = 0;
    int sceondByte = 0;
    int thirdByte = 0;
    int fourthByte = 0;
    int index = 0;
    firstByte = (0x000000FF & ((int) buf[index+3]));
    sceondByte = (0x000000FF & ((int) buf[index+2]));
    thirdByte = (0x000000FF & ((int) buf[index+1]));
    fourthByte = (0x000000FF & ((int) buf[index]));
    anUnsignedInt = ((long) (firstByte << 24 | sceondByte << 16 | thirdByte << 8 | fourthByte)) & 0xFFFFFFFFL;
    return anUnsignedInt ;
}

3.Java中字节转为int

public static int byteArrayToInt(byte[] bytes) {
    int n = 0;
    for (int i = 0; i < 4; i++) {
        n += bytes[i] << i*8;
    }
    return n;
}

二、字节缓冲流

1.基础知识

  • 分配一个指定大小的缓冲区
// 1.分配一个指定大小的缓冲区
ByteBuffer buf = ByteBuffer.allocate(1024);
System.out.println(buf.position); 	//0
System.out.println(buf.limit); 		//1024
System.out.println(buf.capacity); 	//1024
System.out.println(buf.mark); 
  • 利用put()方法进行存储数据
// 2.利用put()方法进行存储数据
String str = "hello nio";
buf.put(str.getBytes());
System.out.println(buf.position); 	//9
System.out.println(buf.limit); 		//1024
System.out.println(buf.capacity); 	//1024
System.out.println(buf.mark); 
  • 切换读取数据的模式
// 3.切换读取数据的模式
buf.flip();
System.out.println(buf.position); 	//0
System.out.println(buf.limit); 		//1024
System.out.println(buf.capacity); 	//1024
System.out.println(buf.mark);
  • 利用get()方法读取数据
// 4.利用get()方法读取数据
byte[] dst = new byte[buf.limit()];
buf.get(dst);
System.out.println(new String(dst, 0, dst.lenth));

System.out.println(buf.position); 	//9
System.out.println(buf.limit); 		//9
System.out.println(buf.capacity); 	//1024
System.out.println(buf.mark

2.String与ByteBuffer转换

import java.nio.ByteBuffer;  
import java.nio.CharBuffer;  
import java.nio.charset.Charset;  
import java.nio.charset.CharsetDecoder;  
  
public class Test {  
    /** 
     * String 转换 ByteBuffer 
     * @param str 
     * @return 
     */  
    public static ByteBuffer getByteBuffer(String str) {  
        return ByteBuffer.wrap(str.getBytes());  
    }  
  
    /** 
     * ByteBuffer 转换 String 
     * @param buffer 
     * @return 
     */  
    public static String getString(ByteBuffer buffer) {  
        Charset charset = null;  
        CharsetDecoder decoder = null;  
        CharBuffer charBuffer = null;  
        try {  
            charset = Charset.forName("UTF-8");  
            decoder = charset.newDecoder();  
            // charBuffer = decoder.decode(buffer);//用这个的话,只能输出来一次结果,第二次显示为空  
            charBuffer = decoder.decode(buffer.asReadOnlyBuffer());  
            return charBuffer.toString();  
        }  
        catch (Exception ex) {  
            ex.printStackTrace();  
            return "";  
        }  
    }  
}

总结

生活, 一半是回忆, 一半是继续。 把所有的不快给昨天, 把所有的希望给明天, 把所有的努力给今天。

在这里插入图片描述

修改加密函数以支持二进制数据%%AES实现 =================================================== function [encrypted, iv_salt] = AES_Encrypt(plaintext, key) % 生成动态salt和iv,各16字节 salt = randi([0 255], 1, 16, 'uint8'); iv = randi([0 255], 1, 16, 'uint8'); iv_salt = [salt iv]; % 合并salt和iv输出(32字节) key = AES_KeyDerivation(key, 16, salt); % 传入动态salt cipher = javax.crypto.Cipher.getInstance('AES/CBC/PKCS5Padding'); cipher.init(javax.crypto.Cipher.ENCRYPT_MODE, ... javax.crypto.spec.SecretKeySpec(key, 'AES'), ... javax.crypto.spec.IvParameterSpec(iv)); % 使用原始iv encrypted = cipher.doFinal(unicode2native(plaintext, 'UTF-8')); encrypted = typecast(encrypted, 'uint8'); encrypted = encrypted(:).'; end function decrypted = AES_Decrypt(ciphertext, key, iv_salt) try % 从合并参数分离salt和iv if length(iv_salt) ~= 32 error('IV/Salt参数长度错误,应为32字节'); end salt = iv_salt(1:16); iv = iv_salt(17:32); % 确保类型正确 salt = uint8(salt); iv = uint8(iv); ciphertext = uint8(ciphertext); % 密钥派生 key = AES_KeyDerivation(key, 16, salt); % 创建Java对象 cipher = javax.crypto.Cipher.getInstance('AES/CBC/PKCS5Padding'); keySpec = javax.crypto.spec.SecretKeySpec(key, 'AES'); ivSpec = javax.crypto.spec.IvParameterSpec(iv); % 初始化解密模式 cipher.init(javax.crypto.Cipher.DECRYPT_MODE, keySpec, ivSpec); % 执行解密 decryptedBytes = cipher.doFinal(ciphertext); decryptedBytes = typecast(decryptedBytes, 'uint8'); % 转换为字符串 decrypted = native2unicode(decryptedBytes, 'UTF-8'); catch ME if contains(ME.message, 'InvalidKeyException') errordlg('密钥错误,请检查加密密钥!','解密失败'); else rethrow(ME); end end end function derivedKey = AES_KeyDerivation(password, keyLength, salt) iterations = 1000000; % 将密码转换为Java char[] passwordChars = java.lang.String(password).toCharArray(); % 将salt转为Java byte[](MATLAB uint8转Java有符号byte) saltBytes = typecast(salt, 'int8'); % 构造密钥规范 spec = javax.crypto.spec.PBEKeySpec(... passwordChars, ... saltBytes, ... iterations, ... keyLength*8); % 生成密钥 factory = javax.crypto.SecretKeyFactory.getInstance('PBKDF2WithHmacSHA256'); tmpKey = factory.generateSecret(spec); derivedKey = typecast(tmpKey.getEncoded(), 'uint8'); end
03-16
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值