You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求助:如何在Swift/Kotlin原生APP中实现ASN.1 UPER解码?

解析ASN.1 UPER编码消息的Kotlin/Swift实现方案

核心前提:吃透UPER编码规则

UPER是ASN.1的压缩位级编码,所有解码逻辑必须基于你的ASN.1语法定义(.asn文件)。先重点掌握常见类型的逆向解码规则:

  • BOOLEAN:读取1位,0对应false,1对应true
  • INTEGER:分两种情况——约束范围(按固定位数读取数值)、无约束(先读长度再读数值)
  • SEQUENCE/SET:按成员顺序依次解码,注意可选字段的存在标记位
  • ENUMERATED:根据枚举值数量确定编码位数,读取数值后映射到对应枚举成员

Kotlin实现思路

Kotlin可借助BitSet处理位操作,先将字节数组转为BitSet,再逐位解析:

1. 基础位读取工具

class BitReader(private val bits: BitSet, private val totalBits: Int) {
    private var position = 0

    fun readBits(count: Int): Int {
        if (position + count > totalBits) throw IllegalArgumentException("Insufficient bits")
        var result = 0
        repeat(count) {
            result = (result shl 1) or (if (bits.get(position++)) 1 else 0)
        }
        return result
    }

    fun readBoolean(): Boolean {
        return readBits(1) == 1
    }
}

2. 具体类型解码示例

解码带约束的INTEGER(范围0-255,占8位):

fun decodeConstrainedInt(reader: BitReader): Int {
    return reader.readBits(8)
}

解码SEQUENCE类型:

data class Device(val deviceId: Int, val isOnline: Boolean)

fun decodeDevice(reader: BitReader): Device {
    val deviceId = decodeConstrainedInt(reader)
    val isOnline = reader.readBoolean()
    return Device(deviceId, isOnline)
}

Swift实现思路

Swift可通过Data配合位掩码操作,或自定义BitReader类处理位偏移:

1. 自定义BitReader工具

class BitReader {
    private let data: Data
    private var byteIndex = 0
    private var bitIndex = 0

    init(data: Data) {
        self.data = data
    }

    func readBits(_ count: Int) -> Int {
        guard byteIndex < data.count || (byteIndex == data.count - 1 && bitIndex + count <= 8) else {
            fatalError("Insufficient bits")
        }
        var result = 0
        var remainingBits = count
        while remainingBits > 0 {
            let availableBits = 8 - bitIndex
            let takeBits = min(remainingBits, availableBits)
            let byte = data[byteIndex]
            let mask = (0xFF >> (8 - takeBits)) << (availableBits - takeBits)
            let bits = (byte & mask) >> (availableBits - takeBits)
            result = (result << takeBits) | Int(bits)
            remainingBits -= takeBits
            bitIndex += takeBits
            if bitIndex == 8 {
                byteIndex += 1
                bitIndex = 0
            }
        }
        return result
    }

    func readBoolean() -> Bool {
        return readBits(1) == 1
    }
}

2. 具体类型解码示例

解码ENUMERATED类型:

enum ConnectionState: Int {
    case disconnected = 0
    case connecting = 1
    case connected = 2
}

func decodeConnectionState(reader: BitReader) -> ConnectionState {
    // 枚举共3个值,需2位编码(2^2 >=3)
    let rawValue = reader.readBits(2)
    return ConnectionState(rawValue: rawValue) ?? .disconnected
}

验证与调试技巧

  • 先用桌面ASN.1工具(如ASN.1 Editor)解码测试数据,得到基准结果,再对照代码调整逻辑
  • 编写单元测试,覆盖所有边界情况:整数最大值、可选字段存在/缺失、枚举边缘值等

这个任务完全可行,核心是拆解ASN.1语法,分类型实现解码逻辑,逐步验证,无需依赖第三方库也能完成。

内容的提问来源于stack exchange,提问作者Ognjen Koprivica

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 15:01:17