确认Buffer

避免Buffer数据混乱的输入处理
博客强调要确认设定的排列或变量大小,避免数据混乱和系统问题。以用户输入城市名称为例,若设定数组长度为10个英文字符,输入超10字会导致程序失败或覆盖Buffer数据。给出修改后的程序,可只接受Buffer能容纳的长度。
部署运行你感兴趣的模型镜像
确认Buffer   

    要时时确认对设定的排列或变量的大小,以避免数据混乱或导致系统出问题。请看下面使用者输入数据的例子:
     char city[10];
    /* 为都市名称的排列 */
    printf("Enter a city name: ");
    scanf("%s", city);
    printf("City is %s/n", city);   
    在这里,都市名称设定为10字(英文字)以内。如果使用者输入10字以上的都市名称会怎么样呢?可以说程序失败或覆盖Buffer里面的数据。不管怎样,不要做冒险的事,你要检查文字的长度:
    char city[10];
    /*为都市名称的排列*/
    printf("Enter a city name: ");
    fgets(city, sizeof(city), stdin);
    printf("City is %s/n", city);   
    上面已修改的程序是:如果使用者输入10字以上的都市名,只接受Buffer能接受的长度为止,其外的会不接受。

您可能感兴趣的与本文相关的镜像

GPT-SoVITS

GPT-SoVITS

AI应用

GPT-SoVITS 是一个开源的文本到语音(TTS)和语音转换模型,它结合了 GPT 的生成能力和 SoVITS 的语音转换技术。该项目以其强大的声音克隆能力而闻名,仅需少量语音样本(如5秒)即可实现高质量的即时语音合成,也可通过更长的音频(如1分钟)进行微调以获得更逼真的效果

private static void orderParse(ByteBuffer buffer, Map<String, Object> mapinfo, String client_id, String task_id) { log.info("=== Order 大端数据解析 ==="); buffer.order(ByteOrder.BIG_ENDIAN); // 1. 地址读取 mapinfo.put("sendAddress", Byte.toUnsignedInt(buffer.get())); mapinfo.put("targetAddress", Byte.toUnsignedInt(buffer.get())); // 2. 保存当前缓冲区状态 buffer.mark(); final int startPos = buffer.position(); // 3. 查找 "trak" 模式 (0x7472616b) final int trakPattern = 0x7472616b; int trakIndex = -1; // 使用只读视图查找 ByteBuffer viewBuffer = buffer.slice().order(ByteOrder.BIG_ENDIAN); for (int i = 0; i <= viewBuffer.remaining() - 4; i++) { if (viewBuffer.getInt() == trakPattern) { trakIndex = viewBuffer.position() - 4; break; } if (viewBuffer.position() > 0) { viewBuffer.position(viewBuffer.position() - 3); } } // 恢复主缓冲区状态 buffer.reset(); if (trakIndex == -1) { mapinfo.put("decryptedData", "未找到 trak 标识"); return; } // 4. 提取加密数据 ByteBuffer encryptedBuffer = buffer.slice().order(ByteOrder.BIG_ENDIAN); encryptedBuffer.limit(trakIndex); // 5. 解密处理 byte[] encryptedBytes = new byte[encryptedBuffer.remaining()]; encryptedBuffer.get(encryptedBytes); String content_encrpy = Base64.getEncoder().encodeToString(encryptedBytes); String decryptedData = decryptProtobufMy(content_encrpy, client_id, task_id); if (decryptedData == null) { mapinfo.put("decryptedData", "解密失败"); return; } // 6. 解析解密数据 byte[] decBytes = Base64.getDecoder().decode(decryptedData); ByteBuffer buf = ByteBuffer.wrap(decBytes).order(ByteOrder.BIG_ENDIAN); mapinfo.put("functionCode", Byte.toUnsignedInt(buf.get())); mapinfo.put("commandCode", Byte.toUnsignedInt(buf.get())); byte[] taskIdBytes = new byte[4]; buf.get(taskIdBytes); mapinfo.put("taskId", new int[]{ Byte.toUnsignedInt(taskIdBytes[0]), Byte.toUnsignedInt(taskIdBytes[1]), Byte.toUnsignedInt(taskIdBytes[2]), Byte.toUnsignedInt(taskIdBytes[3]) }); int dataLength = buf.getInt(); byte[] snData = new byte[dataLength]; buf.get(snData); mapinfo.put("dataLength", dataLength); mapinfo.put("dataHex", bytesToHex(snData)); mapinfo.put("crcCode", Integer.toUnsignedLong(buf.getInt())); // 7. 更新主缓冲区位置(跳过已处理的加密数据 + "trak" 标识) buffer.position(startPos + trakIndex + 4); // +4 for "trak" } 参照private static void trackerParse(ByteBuffer buffer, Map<String, Object> mapinfo) { try{ log.info("=== Tracker 小端数据解析 ==="); buffer.order(ByteOrder.LITTLE_ENDIAN); // 定义目标包头字节("trak" 的 ASCII 值:116, 114, 97, 107) byte[] targetHeader = new byte[] {116, 114, 97, 107}; byte[] header = new byte[4]; int position = -1; // 保存当前 buffer 的 limit int limit = buffer.limit(); // 重置 buffer 位置以便遍历 buffer.rewind(); // 遍历 buffer 查找最后一个匹配的包头 while (buffer.remaining() >= 4) { int startPos = buffer.position(); buffer.get(header); if (Arrays.equals(header, targetHeader)) { position = startPos; // 记录最新找到的包头位置 } buffer.position(startPos + 1); // 移动一位继续查找 } if (position != -1) { buffer.position(position); // 定位到最后一个包头的位置 // 重新读取包头以确认 buffer.get(header); byte cmd = buffer.get(); short length = buffer.getShort(); byte[] ts = new byte[6]; buffer.get(ts); long timestamp = 0; for (int i = ts.length - 1; i >= 0; i--) { timestamp = (timestamp << 8) | (ts[i] & 0xFF); } mapinfo.put("ts", timestamp); Date date = new Date(); date.setTime(timestamp); String uploadtime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(date); mapinfo.put("upload_time", uploadtime); if (String.format("0x%02X", cmd).equals("0x02")) { short crc = buffer.getShort(); } if (String.format("0x%02X", cmd).equals("0x01")) { byte csq = buffer.get(); mapinfo.put("gps_signal", csq); byte gpsMaxSignal = buffer.get(); mapinfo.put("gps_max_signal", gpsMaxSignal); int longitude = buffer.getInt(); mapinfo.put("longitude", longitude / 1e6); int latitude = buffer.getInt(); mapinfo.put("latitude", latitude / 1e6); byte speed = buffer.get(); mapinfo.put("gps_speed", speed); short angle = buffer.getShort(); mapinfo.put("gps_cog", angle); byte[] iccid = new byte[20]; buffer.get(iccid); mapinfo.put("iccid", new String(iccid).trim()); byte[] imei = new byte[15]; buffer.get(imei); mapinfo.put("imei", new String(imei).trim()); int timestamp10 = buffer.getInt(); Date date2 = new Date(); date2.setTime((long) timestamp10 * 1000); // 秒 → 毫秒 String timestamp10Str = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date2); mapinfo.put("tracker_software_version", timestamp10Str); // 小区信息 JSONArray cellList = new JSONArray(); // 创建JSON数组 try{ for (int i = 0; i < 10; i++) { int flag = buffer.getInt(); int cid = buffer.getInt(); int mcc = buffer.getInt(); int mnc = buffer.getInt(); int tac = buffer.getInt(); int pci = buffer.getInt(); int earfcn = buffer.getInt(); int rssi = buffer.getInt(); if (flag == 0 && cid == 0 && mcc == 0 && mnc == 0 && tac == 0 && pci == 0 && earfcn == 0 && rssi == 0) { break; } // 创建单个小区的JSON对象 JSONObject cell = new JSONObject(); cell.put("flag", flag); cell.put("cid", cid); cell.put("mcc", mcc); cell.put("mnc", mnc); cell.put("tac", tac); cell.put("pci", pci); cell.put("earfcn", earfcn); cell.put("rssi", rssi); cellList.add(cell); // 添加到JSON数组 } }catch(Exception e){ e.printStackTrace(); } mapinfo.put("cellList", cellList.toString()); short crc = buffer.getShort(); } } else { log.warn("未找到包头为 'trak' 的数据包"); } }catch(Exception e){ log.info("Tracker树据解析异常"); } } 寻找trak位置截取, public static String convertToHex(String str) { StringBuilder hex = new StringBuilder(); for (int i = 0; i < str.length(); i++) { hex.append(Integer.toHexString(str.charAt(i))); } return hex.toString(); }
10-16
这段代码展示了如何从 `ByteBuffer` 中查找特定标识 `"trak"`(即十六进制的 `0x7472616b`),并根据找到的位置截取数据进行解析。下面是对关键部分的解释: 1. **查找 `"trak"` 标识**: - 使用 `ByteBuffer` 的只读切片 `viewBuffer`,通过遍历缓冲区查找 `0x7472616b`。 - 一旦找到该标识,记录其起始位置 `trakIndex`,并跳出循环。 2. **截取加密数据**: - 使用 `buffer.slice()` 创建一个新的缓冲区视图,其起始位置为原始缓冲区的当前位置,限制为 `trakIndex`。 - 将该切片中的数据读取为字节数组,并进行 Base64 编码,以便传输或解密。 3. **解密与解析**: - 调用 `decryptProtobufMy()` 方法解密数据。 - 如果解密成功,则将解密后的数据再次解析为 `ByteBuffer` 并进行进一步处理(如提取功能码、命令码、任务 ID、数据长度等)。 4. **更新缓冲区位置**: - 解析完成后,将原始缓冲区的位置更新为跳过已处理的数据(包括 `"trak"` 标识)。 以下是完整的查找 `"trak"` 并截取数据的简化版本: ```java public static int findTrakPosition(ByteBuffer buffer) { buffer.mark(); // 保存当前缓冲区状态 final int trakPattern = 0x7472616b; // "trak" 的十六进制表示 int trakIndex = -1; // 创建只读切片用于查找 ByteBuffer viewBuffer = buffer.slice().order(ByteOrder.BIG_ENDIAN); for (int i = 0; i <= viewBuffer.remaining() - 4; i++) { if (viewBuffer.getInt() == trakPattern) { trakIndex = viewBuffer.position() - 4; // 获取起始位置 break; } // 回退 3 个字节以便继续查找 if (viewBuffer.position() > 0) { viewBuffer.position(viewBuffer.position() - 3); } } buffer.reset(); // 恢复缓冲区状态 return trakIndex; } ``` 使用示例: ```java int trakIndex = findTrakPosition(buffer); if (trakIndex == -1) { mapinfo.put("decryptedData", "未找到 trak 标识"); return; } // 截取加密数据部分 ByteBuffer encryptedBuffer = buffer.slice().order(ByteOrder.BIG_ENDIAN); encryptedBuffer.limit(trakIndex); byte[] encryptedBytes = new byte[encryptedBuffer.remaining()]; encryptedBuffer.get(encryptedBytes); String content_encrpy = Base64.getEncoder().encodeToString(encryptedBytes); ``` ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值