Por que não posso ler / dev / urandom no OSX?

27

Um colega sugeriu a criação de uma chave aleatória por meio do seguinte comando:

tr -dc A-Za-z0-9_\!\@\#\$\%\^\&\*\(\)-+= < /dev/urandom | head -c 32 | xargs

Isso me deu o erro:

tr: Illegal byte sequence

Estou preocupado por não ter /dev/urandom no meu sistema. Eu tentei googling para descobrir como instalar este arquivo, mas eu tenho vazio. Eu tentei locate urandom e também cheguei vazio. (bem, na verdade, ele encontrou a man page, mas isso não ajuda)

Como eu faço urandom disponível no meu sistema Mac OSX? (Leão)

    
por Kirk Woll 13.08.2012 / 20:18

6 respostas

42

Com base na mensagem de erro que você recebe, não acho / dev / urandom o problema. Se fosse, esperaria um erro como "nenhum arquivo ou diretório".

Eu procurei a mensagem de erro que você recebeu e a encontrei, o que parece ser relevante para o seu problema: link

Basicamente, especifique a localidade, prefixando o comando tr com LC_CTYPE=C :

LC_CTYPE=C tr -dc A-Za-z0-9_\!\@\#\$\%\^\&\*\(\)-+= < /dev/urandom | head -c 32 | xargs
    
por 13.08.2012 / 20:39
9

Seu tr tenta interpretar sua entrada como texto na codificação UTF-8. Então ele irá reclamar e abortar na primeira seqüência de bytes que não é válida UTF-8. Prefixar tr com LC_ALL=C ou LC_CTYPE=C exportará essa variável para o ambiente de tr , alterando assim sua ideia do conjunto de caracteres local para o padrão C, ou seja, tudo é apenas uma seqüência de bytes opacos.

A propósito, a sequência \)-+ em seu comando é intencional? Isso inclui * , que você já incluiu, mas não inclui - como você poderia ter desejado. É melhor escrever um desses:

LC_ALL=C tr -dc 'A-Za-z0-9_!@#$%^&*()\-+=' < /dev/urandom
LC_CTYPE=C tr -dc A-Za-z0-9_\!\@\#\$\%\^\&\*\(\)\-+= < /dev/urandom
    
por 15.02.2013 / 21:41
5

Como outros indicaram, seu problema não é que /dev/urandom está ausente, mas sim como tr funciona no OS X. Em vez de mexer com varialbes de ambiente, use perl no lugar de tr :

perl -pe 'binmode(STDIN, ":bytes"); tr/A-Za-z0-9_\!\@\#\$\%\^\&\*\(\)-+=//dc;' < /dev/urandom | head -c 32; echo

Isso tem a vantagem de ser portátil em todo o OS X, Redhat e Ubuntu.

(Eu também removi o pipe para xargs , substituindo echo , para obter uma nova linha no final da saída.)

    
por 21.07.2015 / 02:27
1

Primeiramente, você pretende incluir - ou * na lista de caracteres válidos? O parâmetro para tr inclui a sequência )-+ , que significa "o intervalo de bytes começando com ) e terminando com + , que na verdade é )*+ .

Em segundo lugar, em vez de ler muitos kilobytes do pool de entropia do kernel (e assim marcar todo o pool como inseguro, o que afetará qualquer outro processo que precise de entropia segura), considere a leitura de quantos bits forem necessários: use head -c... como a etapa primeiro e, em seguida, traduza em vez de descartar caracteres indesejados.

Esta versão particular do problema é um pouco incomum, pois usa 76 símbolos diferentes; a maioria só quer alfanumérico, então se você estiver satisfeito com apenas 64 símbolos, então usar o utilitário base64 irá minimizar o consumo do pool de entropia (note que 24 é 6/8 de 32):

head -c24 < /dev/random | base64
    
por 25.02.2017 / 13:55
1

A codificação de caracteres do seu código de idioma (que você pode dizer com locale charmap ) é um multi-byte por caractere.

O mais comum hoje em dia é o UTF-8, onde os caracteres podem ser codificados em 1 a 4 bytes. Nem todas as seqüências de bytes formam caracteres válidos em UTF-8. Cada caractere não-ASCII em UTF-8 inicia com um byte que possui os dois bits mais altos e informa quantos bytes com o maior (mas não o segundo maior) conjunto de bits segue.

/dev/urandom contém um fluxo aleatório de bytes. tr transliterates character, então ele precisa decodificar esses bytes como caracteres. Esses caracteres ASCII no seu intervalo são todos codificados em um caractere em UTF-8, mas tr ainda precisa decodificar todos os caracteres. Existem, por exemplo, outras codificações multi-byte em que alguns caracteres diferentes de A contêm o byte 0x41 (o código para A ).

Porque esse fluxo aleatório de bytes é obrigado a conter seqüências inválidas (por exemplo, um byte 0x80 por si só é inválido em UTF-8 como um caractere não-ASCII tem que iniciar com um byte maior que 0xc1 (0xc0 e 0xc1 estão em nenhum caractere UTF-8)), então tr retorna com um erro quando isso acontece.

O que você quer aqui é considerar o fluxo de bytes como caracteres em uma codificação que tenha um byte por caractere. O que você escolher não é importante, pois todos os caracteres do seu intervalo (assumindo por AZ, você significa ABCDEFGHIJKLMNOPQRSTUVWXYZ e não coisas como Ý , Ê ) fazem parte do conjunto de caracteres portáteis, portanto, sejam codificados da mesma forma em todos os conjuntos suportados no seu sistema.

Para isso, você definiria a variável LC_CTYPE localization, que é aquela que decide qual conjunto de caracteres é usado e o que itens como blank , alpha classes de caracteres contêm. Mas para a definição do intervalo A-Z, você também desejará definir a variável LC_COLLATE (aquela que decide sobre a ordenação de string).

O C aka POSIX locale é aquele que garante que os caracteres sejam de um único byte e que A-Z seja ABCDEFGHIJKLMNOPQRSTUVWXYZ. Você poderia fazer:

 LC_CTYPE=C LC_COLLATE=C tr -dc 'A-Za-z0-9_!@#$%^&*()+=-'

(aqui movendo o - para o final, caso contrário, )-+ seria considerado como um intervalo como A-Z )

Mas observe que a variável LC_ALL substitui todas as outras variáveis LC_* e LANG . Então, se LC_ALL já estiver definido, o acima não terá efeito. Então, você pode simplesmente fazer:

 LC_ALL=C tr -dc 'A-Za-z0-9_!@#$%^&*()+=-'

Isso afetará outras coisas, como o idioma das mensagens de erro, mas, de qualquer forma, a alteração de LC_CTYPE já pode ter sido um problema para mensagens de erro (por exemplo, não é possível expressar mensagens de erro russas ou japonesas no conjunto de caracteres C ).

    
por 05.05.2017 / 11:16
0

De acordo com a página de manual , / dev / random provavelmente será suficiente para suas necessidades. Talvez a Apple tenha deixado de criar o / dev / urandom porque é desnecessário?

    
por 13.08.2012 / 20:22

Tags