mirror of
https://github.com/bitcoin-s/bitcoin-s.git
synced 2024-11-20 10:13:26 +01:00
Merge pull request #27 from Christewart/master
Adding utility function to convert a byte to a bit vector and vice versa
This commit is contained in:
commit
7cee065214
@ -89,6 +89,31 @@ trait BitcoinSUtil {
|
||||
val paddedHex = padding.mkString + hex
|
||||
paddedHex
|
||||
}
|
||||
|
||||
/** Converts a sequence of bytes to a sequence of bit vectors - assumes the sequence of bytes are big endian */
|
||||
def bytesToBitVectors(bytes: Seq[Byte]): Seq[Seq[Boolean]] = bytes.map(byteToBitVector)
|
||||
|
||||
/** Converts a byte to a bit vector representing that byte - the bit vector is big endian */
|
||||
def byteToBitVector(byte: Byte): Seq[Boolean] = {
|
||||
(0 to 7).map(index => isBitSet(byte,7 - index))
|
||||
}
|
||||
|
||||
/** Checks if the bit at the given index is set */
|
||||
def isBitSet(byte: Byte, index: Int): Boolean = ((byte >> index) & 1) == 1
|
||||
|
||||
/** Converts a bit vector to a single byte -- assumes the bits are big endian */
|
||||
def bitVectorToByte(bits: Seq[Boolean]): Byte = {
|
||||
require(bits.size <= 8, "Cannot convert a bit vector to a byte when the size of the bit vector is larger than 8, got: " + bits)
|
||||
val b = bits.reverse
|
||||
val result: Seq[Int] = b.zipWithIndex.map { case (b, index) =>
|
||||
if (b) NumberUtil.pow2(index).toInt else 0
|
||||
}
|
||||
result.sum.toByte
|
||||
}
|
||||
|
||||
/** Converts a sequence of bit vectors to a sequence of bytes */
|
||||
def bitVectorsToBytes(bits: Seq[Seq[Boolean]]): Seq[Byte] = bits.map(bitVectorToByte)
|
||||
|
||||
}
|
||||
|
||||
object BitcoinSUtil extends BitcoinSUtil
|
||||
|
@ -1,6 +1,6 @@
|
||||
package org.bitcoins.core.util
|
||||
|
||||
import org.bitcoins.core.gen.StringGenerators
|
||||
import org.bitcoins.core.gen.{CryptoGenerators, NumberGenerator, StringGenerators}
|
||||
import org.scalacheck.{Gen, Prop, Properties}
|
||||
/**
|
||||
* Created by chris on 6/20/16.
|
||||
@ -16,4 +16,15 @@ class BitcoinSUtilSpec extends Properties("BitcoinSUtilSpec") with BitcoinSLogge
|
||||
Prop.forAll(StringGenerators.hexString) { hex : String =>
|
||||
BitcoinSUtil.flipEndianess(BitcoinSUtil.flipEndianess(hex)) == hex
|
||||
}
|
||||
|
||||
property("Convert a byte to a bit vector, convert it back to the original byte") =
|
||||
Prop.forAll { byte: Byte =>
|
||||
BitcoinSUtil.bitVectorToByte(BitcoinSUtil.byteToBitVector(byte)) == byte
|
||||
}
|
||||
|
||||
property("Convert a sequence of bit vectors to a sequence of bytes") =
|
||||
Prop.forAll(NumberGenerator.bitVectors) { bitVectors: Seq[Seq[Boolean]] =>
|
||||
BitcoinSUtil.bytesToBitVectors(BitcoinSUtil.bitVectorsToBytes(bitVectors)) == bitVectors
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -21,4 +21,36 @@ class BitcoinSUtilTest extends FlatSpec with MustMatchers {
|
||||
//fail to parse a hex string that is uneven
|
||||
BitcoinSUtil.isHex("123") must be (false)
|
||||
}
|
||||
|
||||
it must "convert a byte to a bit vector" in {
|
||||
val byte = 0.toByte
|
||||
BitcoinSUtil.byteToBitVector(byte) must be (Seq(false,false,false,false,false,false,false,false))
|
||||
|
||||
val byte1 = 1.toByte
|
||||
BitcoinSUtil.byteToBitVector(byte1) must be (Seq(false,false,false,false,false,false,false,true))
|
||||
|
||||
val byte2 = 2.toByte
|
||||
BitcoinSUtil.byteToBitVector(byte2) must be (Seq(false,false,false,false,false,false,true,false))
|
||||
|
||||
val byte3 = 3.toByte
|
||||
BitcoinSUtil.byteToBitVector(byte3) must be (Seq(false,false,false,false,false,false,true,true))
|
||||
|
||||
val maxByte = 0xff.toByte
|
||||
BitcoinSUtil.byteToBitVector(maxByte) must be (Seq(true,true,true,true,true,true,true,true))
|
||||
}
|
||||
|
||||
it must "convert a bit vector to a byte" in {
|
||||
val bitVector0 = Seq(false,false,false,false,false,false,false,false)
|
||||
BitcoinSUtil.bitVectorToByte(bitVector0) must be (0.toByte)
|
||||
|
||||
val bitVector1 = Seq(false,false,false,false,false,false,false,true)
|
||||
BitcoinSUtil.bitVectorToByte(bitVector1) must be (1.toByte)
|
||||
|
||||
val bitVector2 = Seq(false,false,false,false,false,false,true,false)
|
||||
BitcoinSUtil.bitVectorToByte(bitVector2) must be (2.toByte)
|
||||
|
||||
val bitVectorMax = Seq(true,true,true,true,true,true,true,true)
|
||||
BitcoinSUtil.bitVectorToByte(bitVectorMax) must be (0xff.toByte)
|
||||
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user