我有十六进制值
B455
当我将其更改为二进制时,我得到了
1011 0100 0101 0101
我想用以下规则交换位:
origin bits index : 0123456789ABCDEF
result bits index : D5679123C4EF80AB`
然后我就有结果了
1100 1011 0001 1101
转换为十六进制是
CB1D
你能帮助获得脚本 shell 来执行此操作吗?
提前致谢。
答案1
如前所述,外壳可能不是执行此操作的最佳位置。如果您确实愿意,这里有一个使用awk
、dc
、printf
、sed
和 的解决方案tr
:
#!/bin/sh
# file: swap-bits
target_order='D5679123C4EF80AB'
indices() {
printf '%s\n' "$1" \
| sed 's/./\0 1+p\n/g' \
| sed '1s/^/10o16i/' \
| dc \
| sed 's/^/substr( $0, /' \
| sed 's/$/, 1 )/' \
| tr '\n' ' '
echo
}
sed 's/^/2o16iF/' \
| sed 's/$/p/' \
| dc \
| sed 's/....//' \
| awk "{ print \"16o2i\" $(indices ${target_order}) \"pq\" }" \
| dc \
| sed 's/^/0000/' \
| sed 's/.*\(....\)$/\1/'
这不会检查输入。该target_order
变量应设置为 16 位的首选排列。
该函数indices
将这样的字符串作为输入,并输出一系列substr( $0, n, 1 )
命令,这些命令awk
将用于排列其输入。
脚本的主体首先使用dc
将输入从十六进制转换为二进制。通过在输入前添加 F 前缀并丢弃四个 1 位来保留前导 0 位。结果被送入awk
,它打印一个命令,告诉dc
从二进制转换为十六进制,然后是排列后的输出,然后是一个命令,告诉dc
打印并退出。这当然是输入到dc
.最后,sed
再次使用以确保输出中存在前导零(如果适用)。
输入打开stdin
,输出打开stdout
,如下所示:
$ echo B455 | ./swap-bits
CB15
答案2
perl -wMstrict -le '
my @bits = unpack "(A1)16", sprintf "%016b", hex shift;
my $bitmap = "D5679123C4EF80AB";
@bits = @bits[ map { hex } split //, $bitmap ];
$"="";
print sprintf "%04X", oct "0b@bits";
' "B455"
Result: CB15
简短的:
First we convert the input hex number into it's 16-bit binary equivalent and store the indi-
dual bits in the array @bits. The individual bits are now mapped according to the bitmap wh-
ich is generated by splitting into single bits and getting their decimal equivalents which
are the array indices of @bits. Last step involves in converting the mapped bits into their
4-digit hex counterpart.