I want to achieve 32-bit right rotation with posix shell.

Asked 2 years ago, Updated 2 years ago, 98 views

I wanted to know how far the posix shell alone can calculate, and I wanted to know how bit calculations can be realized.(In particular, I was trying to implement sha256/md5)

I would like to achieve a 32-bit right rotation bit shift operation.How can I do this? The shell has arhythmic expansion, and the numerical type is guaranteed to be signed long, and the bit operators, so I think it will probably be possible.However, I am asking because I am wondering if I could get the bit length of long and what is the correct bit operation based on that.

sh posix

2022-09-30 13:54

2 Answers

I don't know what you want to do, but if it's a 32-bit integer bit shift, it's like this.(I don't think about efficiency)

#!/bin/sh

## 32-bit integer MSB
msb = 2147483648
## MSB with a 33-bit
msbx2 = $(msb*2))

## Test for handling integers greater than 32 bits
[$msbx2-gt$msb]||exit1

while read v;do
  ## round to a 32-bit integer
  v=$(v%msbx2))
  printf'input%8x\n'$v
  printf'right shift: %8x\n'$(v/2)
  printf'left shift: %8x\n'$(v*2%msbx2))
  printf'right rate: %8x\n'$(v/2+v%2*msb))
  printf'left root: %8x\n'$(v*2%msbx2+v/msb))
done


2022-09-30 13:54

I tried implementing right rotation using bit operation in bash.

Code

#!/bin/bash
MAX_BIT_NUM = 64
func(){
    BIT_NUM = $1
    n = $2
    data = $3
    printf"BIT_NUM=%d data=%sn=%-2d"${BIT_NUM}${data}${n}

    DATA_MASK=$(~((-1)<<(BIT_NUM)))))
    if [${DATA_MASK}=0]; then DATA_MASK=-1;fi#overflow
    RIGHT_MASK=$(~(-1<<n)))
    LEFT_MASK=$(-1<<n)&DATA_MASK))

    # Clear out-of-range bits
    data=$(data&DATA_MASK))
    #right data saving
    right=$(data&RIGHT_MASK))
    #n-bit right shift
    data=$(data>>n))
    # 0 clear the portion to be rotated
    data=$((data&(~(RIGHT_MASK<<(BIT_NUM-n)))))))
    # Set saved right data by rotating it.
    data=$((data|(right<<(BIT_NUM-n)))))
    printf"rotete data=0x%016x(%d)\n"${data}${data}
}

[Results]

BIT_NUM=32data=16#a0b0c0d0n=0rotete data=0x000000a0b0c0d0(2695938256)
BIT_NUM=32 data=16#a0b0c0d0n=1 rotete data=0x0000000050586068 (1347969128)
BIT_NUM=32data=16#a0b0c0d0n=2rotete data=0x000000282c3034 (673984564)
BIT_NUM=32data=16#a0b0c0d0n=3rotete data=0x000000001416181a (336992282)
BIT_NUM=32data=16#a0b0c0d0n=4rotete data=0x0000000a0b0c0d(168496141)
BIT_NUM=32 data=16#a0b0c0d0n=31 rotete data=0x000000416181a1 (1096909217)
BIT_NUM=32 data=16#a0b0c0d0n=32 rotete data=0x00000000a0b0c0d0 (2695938256)
BIT_NUM=64 data=16#a0b0c0d0a0b0c0d0n=0rotete data=0xa0b0c0d0a0b0c0d0(-6867777429458337584)
BIT_NUM=64 data=16#a0b0c0d0a0b0c0d0n=4rotete data=0x0a0b0c0d0a0b0c0d (723685415265700877)
BIT_NUM=64 data=16#a0b0c0d0a0b0c0d0n=8 rotete data=0xd0a0b0c0d0a0b0c0 (-3413534175366434624)
BIT_NUM=64 data=16#a0b0c0d0a0b0c0d0n=31 rotete data=0x416181a1416181a1 (471118921479287649)
BIT_NUM=64 data=16#a0b0c0d0a0b0c0d0n=32 rotete data=0xa0b0c0d0a0b0c0d0(-6867777429458337584)

I don't know what long looks like in bash, but I tried to count the bit length of the integer.
  The result was 64.

Code

#!/bin/bash
count = 0
for ((d=1;d!=0;d<<=1))
do
    ((count+=1))
done
printf"count=%d\n"${count}

GNU bash, version 4.4.20(1)-release(x86_64-pc-linux-gnu)


2022-09-30 13:54

If you have any answers or tips


© 2024 OneMinuteCode. All rights reserved.