首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >对字符中的位进行重新索引

对字符中的位进行重新索引
EN

Stack Overflow用户
提问于 2019-06-25 23:42:07
回答 4查看 133关注 0票数 0

我有一个练习,我必须在命令行给出的位级对字符串进行编码和解码。

需要注意的是,我必须使用置换映射来重新排序比特。

下面是一个例子:

用户输入要编码的字符

代码语言:javascript
运行
复制
 H

H的二进制是

代码语言:javascript
运行
复制
 01001000 

然而,这是从0到7的8位的常规映射。

我的程序将不得不将位置换为我使用的任何映射模式。

例如,如果我使用Mapping 64752031

字符'H‘的位

代码语言:javascript
运行
复制
01001000 

转到

代码语言:javascript
运行
复制
01000001

编码字符时,第0位变为第6位,第2位变为第4位,第3位变为第7位,依此类推。该映射所基于的内容。

有没有一种方法可以让我根据给定的排列图来操作和改变位的顺序?

谢谢。

EN

回答 4

Stack Overflow用户

发布于 2019-06-26 00:28:37

如果需要处理大字符串,最好使用预计算转换的查找表。

代码语言:javascript
运行
复制
#include <stdio.h>

unsigned char perm[256];  // permutation table
unsigned mapping[8]={6,4,7,5,2,0,3,1};
// assumes    7 6 5 4 3 2 1 0
//       =>   6 4 7 5 2 0 3 1

void mkperm(unsigned char perm[256]) {
  for (int i=0; i<256; i++)
    perm[i]=0;

  for (int i=0;i<256;i++) {
    for (int j=7; j>=0; j--) {
      int pos=mapping[7-j]; // at mapping[0] is the new position of bit 7
      if (i & (1<<j))       // only considers set bits, the table is previously cleared
        perm[i] |= (1<<pos) ;
    }
  }
}

int main() {
  mkperm(perm);
  printf("%.2x => %.2x\n",'H',perm['H']);
}

mkperm()通过扫描每个字符的连续位来计算排列表。如果在char i中设置了位,我们在转换表中的位置i设置由映射给出的逻辑权重为1的位。通过将单元格i的内容正确移位为1来设置此值。

票数 3
EN

Stack Overflow用户

发布于 2019-06-25 23:47:54

使用按位运算符。

下面是如何将第二位移到第七位的示例:

代码语言:javascript
运行
复制
x |= (x & 1<<1) << 6;
x &= ~(1<<1);

如果我的比特编号打扰了任何人,我很抱歉。这就是我读取二进制数的方法。

您还可以将其放入内联函数中:

代码语言:javascript
运行
复制
inline int bit_mode(int *x, int bit1, int bit2)
{
    *x |= *x & (1<<(bit1-1)) << (bit2-1);
    *x &= ~(1<<(bit1-1));
    return *x;
}

int a;
bit_mode(&a, 2, 7);
票数 1
EN

Stack Overflow用户

发布于 2019-06-26 00:20:12

只需将位移到适当的位置即可。在一些有趣的事情之后,我想我得到了这个:

代码语言:javascript
运行
复制
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <limits.h>
#include <stdint.h>

/**
 * A little helper function
 * get the bit number 'as' from the byte 'in'
 * and put that bit as the number 'num' in the output
 */
static inline
uint8_t map_get_bit_as(uint8_t in, 
  uint8_t num, uint8_t as)
{
  return (!!(in & (1 << as))) << num;
}

uint8_t map(unsigned long mapping, uint8_t in) 
{
  // static_assert(CHAR_BIT == 8, "are you insane?");

  const int bit0 = mapping / 10000000 % 10;
  const int bit1 = mapping / 1000000 % 10;
  const int bit2 = mapping / 100000 % 10;
  const int bit3 = mapping / 10000 % 10;
  const int bit4 = mapping / 1000 % 10;
  const int bit5 = mapping / 100 % 10;
  const int bit6 = mapping / 10 % 10;
  const int bit7 = mapping / 1 % 10;

  return
    map_get_bit_as(in, 0, bit0) |
    map_get_bit_as(in, 1, bit1) |
    map_get_bit_as(in, 2, bit2) |
    map_get_bit_as(in, 3, bit3) |
    map_get_bit_as(in, 4, bit4) |
    map_get_bit_as(in, 5, bit5) |
    map_get_bit_as(in, 6, bit6) |
    map_get_bit_as(in, 7, bit7);
}

int main() {
  printf("%#02x %#02x\n\n", 'H', map(64752031, 'H'));
}

将输出:

代码语言:javascript
运行
复制
0x48 0x41

已在repl上测试。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56757679

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档