从带有位偏移量的std::字符串中按字节提取连续位
Extracting continuos bits from a std::string bytewise with a bit offset
我有点不知所措,我想从一个字符串(来自网络)中提取最多64个具有定义的位偏移量和位长度(无符号长-长)的位。
字符串的长度可以是未定义的,所以我需要确保只按字节访问它。(也意味着我不能使用_bextr_u32内在)。我不能使用std位集类,因为它不允许提取超过一个带有偏移量的位,而且只允许提取预定义数量的位。
所以我已经计算了字节偏移量(在字符串中)和比特偏移量(起始字节中)。
m_nByteOffset = nBitOffset / 8;
m_nBitOffset = nBitOffset % 8;
现在我可以得到起始地址
const char* sSource = str.c_str()+m_nByteOffset;
和位掩码
unsigned long long nMask = 0xFFFFFFFFFFFFFFFFULL >> (64-nBitLen);
但现在我不知道如何从中提取64位,因为没有128位整数可用。
unsigned long long nResult = ((*(unsigned long long*)sSource) >> m_nBitOffset) & nMask;
这只适用于最多64位的偏移位,我如何才能将其扩展到真正适用于64位的独立偏移位。而且由于这不是按字节访问,它可能会导致内存读取访问冲突。
所以我真的在寻找一个字节式的解决方案来解决这个问题,它最多可以工作64位。(最好是C或内部)
更新:在搜索和测试了很多之后,我可能会使用RakNet的这个功能:https://github.com/OculusVR/RakNet/blob/master/Source/BitStream.cpp#L551
要按字节执行,只需一次读取一个字节的字符串(BTW最好将其解释为uint8_t
序列,而不是char
序列),通过将其向左移动8并用当前字节or
来更新结果。唯一复杂的是第一位和最后一位,这两个位都需要读取字节的一部分。对于第一部分,只需使用位掩码来获得所需的位,对于最后一部分,则将其下移所需的量。这是代码:
const uint8_t* sSource = reinterpret_cast<const uint8_t*>(str.c_str()+m_nByteOffset);
uint64_t result = 0;
uint8_t FULL_MASK = 0xFF;
if(m_nBitOffset) {
result = (*sSource & (FULL_MASK >> m_nBitOffset));
nBitLen -= (8 - m_nBitOffset);
sSource++;
}
while(nBitLen > 8) {
result <<= 8;
result |= *sSource;
nBitLen -= 8;
++sSource;
}
if(nBitLen) {
result <<= nBitLen;
result |= (*sSource >> (8 - nBitLen));
}
return result;
这就是我在现代C++风格中的做法。比特长度由缓冲区extractedBits
的大小决定:您也可以使用所需大小的任何其他数据类型(甚至数组类型),而不是使用unsigned long long
。
实时查看
unsigned long long extractedBits;
char* extractedString = reinterpret_cast<char*>(&extractedBits);
std::transform(str.begin() + m_nByteOffset,
str.begin() + m_nByteOffset + sizeof(extractedBits),
str.begin() + m_nByteOffset + 1,
extractedString,
[=](char c, char d)
{
char bitsFromC = (c << m_nBitOffset);
char bitsFromD =
(static_cast<unsigned char>(d) >> (CHAR_BIT - m_nBitOffset));
return bitsFromC | bitsFromD;
});
- 从不同线程使用int64的不同字节安全吗
- 将Integer转换为4字节的unsined字符矢量(按大端字节顺序)
- 模板元程序查找相似的连续类型名称
- 在UNIX系统中使用DIR查找文件的字节大小
- 如何使用Crypto++并为RSA返回可打印的字节/字符数组
- std::当在256字节边界上写入整数时,流的奇怪行为
- 当比特(而不是字节)的顺序至关重要时的持久性
- EASTL矢量<向量<int>>连续的
- 从文件中读取多个字节,并将它们存储在C++中进行比较
- 如何在文件中查找字节序列
- luaL_dofile在已知良好的字节码上失败,可以使用未编译的版本
- 当需要超过16GB的连续内存时,内存分配失败
- 字节到位运算符重载C++
- 在java中读取c++字节的位字段
- 如何使用 fprintf 将连续的 512 字节保存到文件中
- 从带有位偏移量的std::字符串中按字节提取连续位
- 将连续字节作为一个整数读取
- 解析来自固定大小字节缓冲区的连续块的protobuf消息序列
- 为什么在visual studio中连续的int数据类型变量位于12个字节的偏移
- 从技术上讲,对象是否可以占用不连续字节的存储空间