Hell of a time extracting bits from a vector

I

Idgarad

I am generating a SHA1 digest that I want to use for some values.

I want to take the digest that is generated at extact a given number
of bits, in sequence.

SHA1 generates 160 bits.

I would like to partition that 160 bits into an array storing the
value of those bits

for instance (in short form using only 10 bits grabbing 2 at a time)
lets say I have:

1010010101

and I am grabbing pairs I need (from least to most):

@somearray

$somearray[0] = 1 (01)
$somearray[1] = 1 (01)
$somearray[2] = 1 (01)
$somearray[3] = 2 (10)
$somearray[4] = 2 (10)


I I tried using vec (going back to the full 160 bits) but it fails
miserably. Here a sample

Using vec($digest,$loop*8,8) (Grabbing 8 bits)

I would get
0101010101
1101011010
100101001010101101
010110110101011101
....

The lengths would be wrong (doing an unpack "b*" on the array that was
holding the result. Sometimes I would get 8, other 16 and the number
even changes running the same data!)

I even tried using the Binary::Vector with a Chunk_Read and got
similar results.

This should be this hard to just extract X bits from a Y*X offset
where Y is the loop iteration.

What am I missing?
 
J

John W. Krahn

Idgarad said:
I am generating a SHA1 digest that I want to use for some values.

I want to take the digest that is generated at extact a given number
of bits, in sequence.

SHA1 generates 160 bits.

I would like to partition that 160 bits into an array storing the
value of those bits

use Digest::SHA1 qw(sha1);

unpack '(a)*', unpack 'B*', sha1( $data );

for instance (in short form using only 10 bits grabbing 2 at a time)
lets say I have:

1010010101

and I am grabbing pairs I need (from least to most):

@somearray

$somearray[0] = 1 (01)
$somearray[1] = 1 (01)
$somearray[2] = 1 (01)
$somearray[3] = 2 (10)
$somearray[4] = 2 (10)

my @somearray = unpack '(a2)*', unpack 'B*', sha1( $data );



John
 
C

comp.llang.perl.moderated

I am generating a SHA1 digest that I want to use for some values.

I want to take the digest that is generated at extact a given number
of bits, in sequence.

SHA1 generates 160 bits.

I would like to partition that 160 bits into an array storing the
value of those bits

for instance (in short form using only 10 bits grabbing 2 at a time)
lets say I have:

1010010101

and I am grabbing pairs I need (from least to most):

@somearray

$somearray[0] = 1 (01)
$somearray[1] = 1 (01)
$somearray[2] = 1 (01)
$somearray[3] = 2 (10)
$somearray[4] = 2 (10)

I I tried using vec (going back to the full 160 bits) but it fails
miserably. Here a sample

Using vec($digest,$loop*8,8) (Grabbing 8 bits)

I would get
0101010101
1101011010
100101001010101101
010110110101011101
...

The lengths would be wrong (doing an unpack "b*" on the array that was
holding the result. Sometimes I would get 8, other 16 and the number
even changes running the same data!)

you are probably forgetting that you need
to pack to an integer or short before you
you unpack to the bit string, eg,

# perl -le 'print unpack "B*",136'
001100010011001100110110

vs.

# perl -le 'print unpack "B*",pack("S",136)'
0000000010001000
 
I

Idgarad

Idgarad said:
I am generating a SHA1 digest that I want to use for some values.
I want to take the digest that is generated at extact a given number
of bits, in sequence.
SHA1 generates 160 bits.
I would like to partition that 160 bits into an array storing the
value of those bits

use Digest::SHA1  qw(sha1);

unpack '(a)*', unpack 'B*', sha1( $data );
for instance (in short form using only 10 bits grabbing 2 at a time)
lets say I have:
1010010101

and I am grabbing pairs I need (from least to most):
@somearray

$somearray[0] = 1 (01)
$somearray[1] = 1 (01)
$somearray[2] = 1 (01)
$somearray[3] = 2 (10)
$somearray[4] = 2 (10)

my @somearray = unpack '(a2)*', unpack 'B*', sha1( $data );

John

Exactly what I was looking for with one exception, I don't want to
store the ASCII in the array but rather the actual integer value.

my @somearray = unpack '(a2)*', unpack 'B*', sha1( $data );

Works perfect but I tried changing the a2 to N or n but that fails
miserable. I figure I have to append an bin to int of some sort to the
front of the unpacks but so far I have been unsuccessful. Any
suggestions?
 
B

Ben Morrow

Quoth Idgarad said:
Exactly what I was looking for with one exception, I don't want to
store the ASCII in the array but rather the actual integer value.

my @somearray = unpack '(a2)*', unpack 'B*', sha1( $data );

Works perfect but I tried changing the a2 to N or n but that fails
miserable. I figure I have to append an bin to int of some sort to the
front of the unpacks but so far I have been unsuccessful. Any
suggestions?

The obvious way is to add

map { oct "0b$_" }

to the front; there may be a cleverer way with pack, but if you don't
need speed that's nice and simple.

Ben
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,764
Messages
2,569,567
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top