Bash é a ferramenta errada. As conchas são boas para juntar pedaços; o processamento de texto e a aritmética são fornecidos ao lado e o processamento de dados não está em sua competência.
Eu preferiria Python por Perl, porque o Python tem bignums logo de cara. Use struct.unpack
para descompactar os dados.
#!/usr/bin/env python
import os, struct, sys
fmt = "<" + "Q" * 8192
header_bytes = sys.stdin.read(65536)
header_ints = list(struct.unpack(fmt, header_bytes))
sys.stdin.seek(-65536, 2)
footer_bytes = sys.stdin.read(65536)
footer_ints = list(struct.unpack(fmt, header_bytes))
# your calculations here
Aqui está a minha resposta à pergunta original. A questão revisada não tem muito a ver com o original, que foi sobre a conversão de uma seqüência de 8 bytes no inteiro de 64 bits que ela representa na ordem little-endian.
Eu não acho que o bash tenha algum recurso embutido para isso. O snippet a seguir define a
para uma string que é a representação hexadecimal do número que corresponde aos bytes na string especificada na ordem big endian .
a=0x$(printf "%s" "$string" |
od -t x1 -An |
tr -dc '[:alnum:]')
Para a ordem little-endian, inverta a ordem dos bytes na string original. No bash, e para uma string de tamanho conhecido, você pode fazer
a=0x$(printf "%s" "${string:7:1}${string:6:1}${string:5:1}${string:4:1}${string:3:1}${string:2:1}${string:1:1}${string:0:1}" |
od -t x1 -An |
tr -dc '[:alnum:]')
Você também pode obter o endianness preferido da sua plataforma se o seu od
oferecer suporte a tipos de 8 bytes.
a=0x$(printf "%s" "$string" |
od -t x8 -An |
tr -dc '[:alnum:]')
Se você pode fazer aritmética em $a
vai depender se o seu bash suporta aritmética de 8 bytes. Mesmo que isso aconteça, ele será tratado como um valor assinado.
Como alternativa, use Perl:
a=0x$(perl -e 'print unpack "Q<", $ARGV[0]' "$string")
Se o seu perl é compilado sem suporte a números inteiros de 64 bits, você precisará quebrar os bytes.
a=0x$(perl -e 'printf "%x%08x\n", reverse unpack "L<L<", $ARGV[0]' "$string")
(Substitua <
por >
para big-endian ou remova-o para obter o endianness da plataforma.)