Kolega zaproponował utworzenie losowego klucza za pomocą następującego polecenia:
tr -dc A-Za-z0-9_\!\@\#\$\%\^\&\*\(\)-+= < /dev/urandom | head -c 32 | xargs
Dał mi błąd:
tr: niedozwolona sekwencja bajtów
Obawiam się, że nie mam /dev/urandom
w moim systemie. Próbowałem google, aby dowiedzieć się, jak zainstalować ten plik, ale wyszedłem pusty. Próbowałem locate urandom
i też wyszedłem pusty. (no cóż, właściwie znalazł stronę man, ale to nie pomaga)
Jak mogę urandom
udostępnić w moim systemie Mac OSX? (Lew)
xargs
...Odpowiedzi:
Na podstawie otrzymanego komunikatu o błędzie nie sądzę, że problem dotyczy / dev / urandom. Gdyby tak było, oczekiwałbym błędu typu „brak takiego pliku lub katalogu”.
Poszukałem otrzymanego komunikatu o błędzie, który wydaje się być odpowiedni dla Twojego problemu: http://nerdbynature.de/s9y/2010/04/11/tr-Illegal-byte-sequence
Zasadniczo określ ustawienia regionalne, poprzedzając
tr
polecenie za pomocąLC_CTYPE=C
:źródło
urandom
lubrandom
? Czy są to specjalne magiczne „pliki”, które nie istnieją w rzeczywistym systemie plików? (Również zasugerowałem edycję, aby złagodzić gnicie linków)locate
że nie przeszukuje bezpośrednio twojego systemu plików, a raczej wyszukuje zapytanie przy użyciu wstępnie zbudowanej bazy danych. Ta baza danych jest najprawdopodobniej skonfigurowana do ignorowania / dev / i innych „specjalnych” systemów plików./dev
. Domyśl. Ale jeszcze raz dziękuję za pomoc.LC_ALL=C
załatwia sprawę.tr
informacji.Twoje
tr
próby interpretacji jego danych wejściowych jako tekstu w kodowaniu UTF-8. Będzie więc narzekał i przerywał pierwszą sekwencję bajtów, która nie jest poprawna UTF-8. Prefikstr
zLC_ALL=C
lubLC_CTYPE=C
spowoduje wyeksportowanie tej zmiennej do środowiskatr
, zmieniając w ten sposób jej koncepcję lokalnego zestawu znaków na standard C, tzn. Wszystko jest tylko sekwencją nieprzezroczystych bajtów.Nawiasem mówiąc, czy sekwencja
\)-+
w twoim poleceniu jest celowa? Dotyczy to*
również tego, co już uwzględniłeś, ale nie obejmuje-
siebie, jak mogłeś sobie wyobrazić. Zamiast tego lepiej napisać jeden z nich:źródło
Jak zauważyli inni, problemu nie
/dev/urandom
brakuje, ale raczej to, jaktr
działa system OS X. Zamiast bawić się różnymi wariantami środowiska, użyjperl
zamiasttr
:Ma to tę zaletę, że jest przenośny w systemach OS X, Redhat i Ubuntu.
(Usunąłem również potok
xargs
, zastępując czarownicęecho
, aby uzyskać nowy wiersz na końcu wyjścia).źródło
binmode ":utf8"
standard, w którym to momencie twoje rozwiązanie Perla będzie miało ten sam problem,tr
co on.Po pierwsze, czy zamierzałeś umieścić
-
lub*
na liście prawidłowych znaków? Parametrtr
obejmujący sekwencję,)-+
który oznacza „zakres bajtów rozpoczynający się)
i kończący na+
, który jest w rzeczywistości)*+
.Po drugie, zamiast odczytywać wiele kilobajtów z puli entropii jądra (a tym samym oznaczać całą pulę jako niepewną, co wpłynie na wszelkie inne procesy wymagające bezpiecznej entropii), rozważ odczyt tylko tyle bitów, ile potrzebujesz: użyj
head -c...
jako pierwszego kroku, a następnie tłumaczyć, zamiast odrzucać niechciane postacie.Ta szczególna wersja problemu jest nieco niezwykła, ponieważ używa 76 różnych symboli; większość po prostu chce alfanumerycznych, więc jeśli będziesz zadowolony tylko z 64 symboli, to użycie
base64
narzędzia zminimalizuje zużycie puli entropii (zauważ, że 24 to 6/8 z 32):źródło
Kodowanie znaków twojego regionu (które możesz rozpoznać
locale charmap
) jest wielobajtowe na znak.Najpopularniejszym obecnie jest UTF-8, w którym znaki mogą być zakodowane w zakresie od 1 do 4 bajtów. Nie wszystkie sekwencje bajtów tworzą prawidłowe znaki w UTF-8. Każdy znak inny niż ASCII w UTF-8 zaczyna się od jednego bajtu, który ma dwa najwyższe ustawione bity i mówi, ile bajtów ma najwyższy (ale nie drugi najwyższy) zestaw bitów.
/dev/urandom
zawiera losowy strumień bajtów.tr
transliteruje znak, więc musi dekodować te bajty jako znaki. Wszystkie znaki ASCII z twojego zakresu są zakodowane na jednym znaku w UTF-8, aletr
nadal muszą dekodować wszystkie znaki. Istnieją na przykład inne kodowania wielobajtowe, w których niektóre znaki inne niżA
zawierają bajt 0x41 (kod dlaA
).Ponieważ ten losowy strumień bajtów musi zawierać nieprawidłowe sekwencje (na przykład sam bajt 0x80 jest niepoprawny w UTF-8, ponieważ znak spoza ASCII musi zaczynać się bajtem większym niż 0xc1 (0xc0 i 0xc1 nie ma UTF- 8 znaków)), więc
tr
powraca z błędem, gdy tak się dzieje.To, czego chcesz tutaj, to wziąć pod uwagę ten strumień bajtów jako znaków w kodowaniu, które ma jeden bajt na znak. Cokolwiek wybierzesz, nie jest ważne, ponieważ wszystkie te znaki z twojego zakresu (zakładając, że AZ miał na myśli ABCDEFGHIJKLMNOPQRSTUVWXYZ, a nie rzeczy takie jak
Ý
,Ê
) są częścią przenośnego zestawu znaków, więc koduj to samo we wszystkich zestawach znaków obsługiwanych w twoim systemie.Do tego, można ustawić
LC_CTYPE
zmienną lokalizacji, która jest tym, który decyduje, które charset jest używany i co takie rzeczyblank
,alpha
klas postaci zawierać. Ale dla definicji zakresu AZ będziesz również chciał ustawićLC_COLLATE
zmienną (tę, która decyduje o kolejności ciągów).C
AkaPOSIX
locale to taki, który gwarantuje znaki są jedno- bajtów i AZ jest ABCDEFGHIJKLMNOPQRSTUVWXYZ. Mógłbyś:(tutaj przesuwanie
-
do końca, w przeciwnym razie)-+
byłoby przyjmowane jako zasięg podobny doA-Z
)Należy jednak pamiętać, że
LC_ALL
zmienna zastępuje wszystkie pozostałeLC_*
iLANG
zmienne. Tak więc, jeśliLC_ALL
inaczej jest już zdefiniowane, powyższe nie przyniesie efektu. Zamiast tego możesz po prostu zrobić:Wpłynie to na inne rzeczy, takie jak język komunikatów o błędach, ale w każdym razie zmiana LC_CTYPE mogła już stanowić problem w przypadku komunikatów o błędach (na przykład brak możliwości wyrażenia rosyjskich lub japońskich komunikatów o błędach w zestawie znaków regionu C).
źródło
Według strony man , / dev / random jest prawdopodobnie będzie wystarczający dla Twoich potrzeb. Być może Apple przestało tworzyć / dev / urandom, ponieważ jest to niepotrzebne?
źródło
/dev/random
.