Logo

Programming-Idioms

This language bar is your friend. Select your favorite languages!

Idiom #275 Binary digits to byte array

From the string s consisting of 8n binary digit characters ('0' or '1'), build the equivalent array a of n bytes.
Each chunk of 8 binary digits (2 possible values per digit) is decoded into one byte (256 possible values).

import re
p = re.compile('.{8}').findall(s)
f = lambda x: int(x, 2)
a = list(map(f, p))
f = lambda x: int(s[x:x + 8], 2)
a = list(map(f, range(0, len(s), 8)))
n = (len(s) - 1) // 8 + 1
a = bytearray(n)
for i in range(n):
    b = int(s[i * 8:(i + 1) * 8], 2)
    a[i] = b
from itertools import batched
f = lambda x: int(''.join(x), 2)
a = list(map(f, batched(s, 8)))
#include <string>
#include <vector>
using namespace std;
const size_t n = s.length() / 8;

vector<uint8_t> a(n);

for(size_t block = 0; block < n; block++)
{
    uint8_t acc = 0;
    const size_t start = block * 8;
    for(size_t offset = start; offset < start + 8; offset++)
    {
        acc = (acc << 1) + (s[offset] - '0');
    }

    a[block] = acc;
}
using System;
using System.Linq;
var a = Enumerable.Range(0, s.Length / 8)
        .Select(i => s.Substring(i * 8, 8).ToCharArray())
        .Select(block => (byte)block.Aggregate(0, (acc, c) => (acc << 1) + (c - '0')))
        .ToArray();
  subroutine to_s (s, a)
    use iso_fortran_env, only: int8
    character (len=*), intent(in) :: s
    integer (kind=int8), allocatable, intent(out), dimension(:) :: a
    allocate (a(len(s)/8))
    read (unit=s,fmt='(*(B8.8))') a
  end subroutine to_s
import "strconv"
n := len(s) / 8
a := make([]byte, n)
for i := range a {
	b, err := strconv.ParseInt(s[i*8:i*8+8], 2, 0)
	if err != nil {
		log.Fatal(err)
	}
	a[i] = byte(b)
}
import static java.lang.Integer.parseInt;
int i, m = s.length(), n = (m + 1) / 8, t;
byte a[] = new byte[n];
for (i = 0; i < m; i = i + 8) {
    t = parseInt(s.substring(i, i + 8), 2);
    a[i / 8] = (byte) t;
}
  Size := Length(S) div 8;
  SetLength(a, Size);
  for i := 0 to Size - 1 do
  begin
    SBin := '%' + Copy(S, 1+(i*8), 8);
    Val(SBin, a[i], Err);
    if (Err <> 0) then
      RunError(106);  
  end;
my $s = '1000' . '0010' . '0101' . '1010';   # AZ

my @a;
for ( my $i = 0; $i < length $s; $i += 8) {
    my @b = pack 'b8', substr($s, $i, 8);
    push @a, @b;
}
a = s.scan(/[01]{8}/).map{|slice| slice.to_i(2).to_s(16).rjust(2, "0")}
let a: Vec<u8> = s.as_bytes()
    .chunks(8)
    .map(|chunk| unsafe {
        let chunk_str = std::str::from_utf8_unchecked(chunk);
        u8::from_str_radix(chunk_str, 2).unwrap_unchecked()
    })
    .collect();

New implementation...
< >
programming-idioms.org