Reputation: 371
Here simple working code to left shift first bit of a byte
package main
import (
"fmt"
)
type Byte byte
func SL(b Byte) Byte {
if b&0x80 == 0x80 {
b <<= 1
b ^= 0x01
} else {
b <<= 1
}
return b
}
func main() {
var b Byte
b = 0xD3
fmt.Printf("old byte %#08b\n", b) // 11010011
c := SL(b)
fmt.Printf("new byte %#08b", c) // 10100111
}
What should I do to shift array of bytes, like
type Byte [2]byte
?
Thanks for advance!
Upvotes: 5
Views: 8524
Reputation: 18557
Here's an implementation that can do both left and right shifts:
// ShiftLeft performs a left bit shift operation on the provided bytes.
// If the bits count is negative, a right bit shift is performed.
func ShiftLeft(data []byte, bits int) {
n := len(data)
if bits < 0 {
bits = -bits
for i := n - 1; i > 0; i-- {
data[i] = data[i]>>bits | data[i-1]<<(8-bits)
}
data[0] >>= bits
} else {
for i := 0; i < n-1; i++ {
data[i] = data[i]<<bits | data[i+1]>>(8-bits)
}
data[n-1] <<= bits
}
}
Upvotes: 3
Reputation: 2222
shift left by multiple bits, expanding qin's answer:
func shiftBytesLeft(a []byte, byBits int) (dst []byte) {
n := len(a)
dst = make([]byte, n)
for i := 0; i < n-1; i++ {
dst[i] = a[i] << byBits
dst[i] = (dst[i] & (0xff - byte(byBits))) | (a[i+1] >> (8 - byte(byBits)))
}
dst[n-1] = a[n-1] << byBits
return dst
}
Upvotes: 2
Reputation: 1713
A solution to shift left 1 bit.
func shiftBytesLeft(a []byte) (dst []byte) {
n := len(a)
dst = make([]byte, n)
for i := 0; i < n-1; i++ {
dst[i] = a[i] << 1
dst[i] = (dst[i] & 0xfe) | (a[i+1] >> 7)
}
dst[n-1] = a[n-1] << 1
return dst
}
Upvotes: 4
Reputation: 7888
You appear to want to rotate, not shift. Any particular reason you aren't using a uint16
type instead of [2]byte
?
Anyway, if you really want [2]byte
, this is simpler and doesn't branch:
func rol(v [2]byte) [2]byte {
x := int(v[0])<<8 | int(v[1])
x <<= 1
v[0] = byte(x >> 8)
v[1] = byte((x & 0xff) | x>>16)
return v
}
If you want to do such operations on an arbitrary large number of bits you could use math/big
.
Upvotes: 3
Reputation: 371
Yep! I found a solution.
package main
import (
"fmt"
)
type Byte [2]byte
//shift left
func SL(b Byte) Byte {
if b[0]&0x80 == 0x80 {
b[0] <<= 1
if b[1]&0x80 == 0x80 {
b[0] ^= 1
b[1] <<= 1
} else {
b[1] <<= 1
}
b[1] ^= 0x01
} else {
b[0] <<= 1
if b[1]&0x80 == 0x80 {
b[0] ^= 1
b[1] <<= 1
} else {
b[1] <<= 1
}
}
return b
}
func main() {
//var b Byte
b := Byte{0x23, 0x86}
fmt.Printf("old byte %#08b %#08b\n", b[0], b[1]) // 00100011 10000110
c := SL(b)
fmt.Printf("new byte %#08b %#08b", c[0], c[1]) // 01000111 00001100
}
Upvotes: 1