동료는 다음 명령을 통해 임의의 키를 만들 것을 제안했습니다.
tr -dc A-Za-z0-9_\!\@\#\$\%\^\&\*\(\)-+= < /dev/urandom | head -c 32 | xargs
그것은 나에게 오류를 주었다 :
tr : 잘못된 바이트 시퀀스
/dev/urandom
시스템에 없는 것이 걱정 됩니다. 이 파일을 설치하는 방법을 찾기 위해 인터넷 검색을 시도했지만 비어 있습니다. 나는 노력 locate urandom
하고 또한 비어 있었다. (실제로 man 페이지를 찾았지만 도움이되지 않습니다)
urandom
Mac OSX 시스템에서 어떻게 사용할 수 있습니까? (사자)
답변
오류 메시지에 따르면 / dev / urandom이 문제라고 생각하지 않습니다. 그렇다면 “파일 또는 디렉토리가 없습니다”와 같은 오류가 발생합니다.
귀하가 얻은 오류 메시지를 검색하여 문제와 관련이있는 것 같습니다 : http://nerdbynature.de/s9y/2010/04/11/tr-Illegal-byte-sequence
기본적으로 tr
명령 앞에 다음을 추가하여 로케일을 지정하십시오 LC_CTYPE=C
.
LC_CTYPE=C tr -dc A-Za-z0-9_\!\@\#\$\%\^\&\*\(\)-+= < /dev/urandom | head -c 32 | xargs
답변
귀하의 tr
시도는 UTF-8 인코딩 텍스트로 입력을 해석합니다. 따라서 유효한 UTF-8이 아닌 첫 번째 바이트 시퀀스를 불평하고 중단합니다. 접두어를 tr
사용 LC_ALL=C
하거나 LC_CTYPE=C
해당 변수를 환경으로 내 보내면 tr
로컬 문자 세트에 대한 아이디어가 C 표준으로 변경됩니다. 즉, 모든 것이 불투명 한 바이트 시퀀스입니다.
그건 그렇고, \)-+
당신의 명령 의 순서 는 의도적 인 것입니까? 여기에는 *
이미 포함했지만 -
의도 한대로 포함되지 않습니다 . 대신 다음 중 하나를 작성하는 것이 좋습니다.
LC_ALL=C tr -dc 'A-Za-z0-9_!@#$%^&*()\-+=' < /dev/urandom
LC_CTYPE=C tr -dc A-Za-z0-9_\!\@\#\$\%\^\&\*\(\)\\-+= < /dev/urandom
답변
다른 사람들이 지적했듯이, 당신의 문제는 /dev/urandom
빠진 것이 아니라 오히려 tr
OS X에서 어떻게 작동 하는지 perl
입니다 tr
.
perl -pe 'binmode(STDIN, ":bytes"); tr/A-Za-z0-9_\!\@\#\$\%\^\&\*\(\)-+=//dc;' < /dev/urandom | head -c 32; echo
이것은 OS X, Redhat 및 Ubuntu에서 이식 가능하다는 이점이 있습니다.
(또한 출력 끝에서 개행을 얻기 위해 xargs
witch를 대체 하는로 파이프를 제거했습니다 echo
.)
답변
첫째, 당신은 포함하려는 않았다 -
또는 *
유효한 문자 목록에? 행의 매개 변수 tr
시퀀스가 포함 )-+
되는 바이트 범위로 시작 “을 의미 )
하고 끝나는 +
사실이다를 )*+
.
둘째, 커널의 엔트로피 풀에서 많은 킬로바이트를 읽지 않고 (전체 풀을 안전하지 않은 것으로 표시하여 안전한 엔트로피가 필요한 다른 프로세스에 영향을 미침), 필요한만큼만 읽기를 고려 head -c...
하십시오. 첫 번째 단계로 사용, 원하지 않는 문자를 버리지 말고 번역하십시오.
이 문제의이 특정 버전은 76 개의 다른 기호를 사용한다는 점에서 약간 특이합니다. 대부분 영숫자를 원하므로 64 기호만으로도 만족한다면 base64
유틸리티 를 사용 하면 엔트로피 풀의 소비가 최소화됩니다 (24는 32의 6/8 임).
head -c24 < /dev/random | base64
답변
로케일의 문자 인코딩 (로 알 수 있음 locale charmap
)은 문자 당 멀티 바이트입니다.
오늘날 가장 일반적인 것은 문자가 1-4 바이트 이상 인코딩 될 수있는 UTF-8입니다. 모든 바이트 시퀀스가 UTF-8에서 유효한 문자를 형성하는 것은 아닙니다. UTF-8의 모든 비 ASCII 문자는 2 개의 가장 높은 비트 세트가있는 1 바이트로 시작하여 가장 높은 (그러나 2 번째가 아닌) 비트 세트가 따르는 바이트 수를 알려줍니다.
/dev/urandom
임의의 바이트 스트림을 포함합니다. tr
문자를 음역하므로 해당 바이트를 문자로 디코딩해야합니다. 범위의 ASCII 문자는 모두 UTF-8로 한 문자로 인코딩되지만 tr
여전히 모든 문자를 디코딩해야합니다. 예를 들어 A
0x41 바이트 이외의 일부 문자 (에 대한 코드)를 포함하는 다른 멀티 바이트 인코딩이 있습니다 A
.
임의의 바이트 스트림이 유효하지 않은 시퀀스를 포함하도록 바인드되기 때문에 (예를 들어, ASCII가 아닌 문자는 0xc1보다 큰 바이트로 시작해야하기 때문에 0x80 바이트 자체는 UTF-8에서 유효하지 않습니다 (0xc0 및 0xc1은 UTF- 8 자)))이므로 tr
오류가 발생하면 오류와 함께 반환됩니다.
여기서 원하는 것은 문자 당 1 바이트를 갖는 인코딩에서 바이트 스트림을 문자로 간주하는 것입니다. AZ가 가정하고 ABCDEFGHIJKLMNOPQRSTUVWXYZ를 의미하고 Ý
, 와 같은 것은 아니라는 것을 의미 Ê
하므로) 범위의 모든 문자가 휴대용 문자 세트의 일부이므로 시스템에서 지원되는 모든 문자 세트에서 동일하게 인코딩되므로 선택하는 것이 중요하지 않습니다 .
이를 위해, 당신은 설정 한 것 LC_CTYPE
사용하고 무엇을 같은 것들을되는 캐릭터 세트 결정하는 하나 현지화 변수 blank
, alpha
문자 클래스가 포함되어 있습니다. 그러나 AZ 범위의 정의를 위해 LC_COLLATE
변수 (문자열 순서를 결정 하는 변수) 도 설정해야 합니다.
C
일명 POSIX
로케일은 하나의 보장 문자임을 단일 바이트이고 AZ는 ABCDEFGHIJKLMNOPQRSTUVWXYZ입니다. 당신은 할 수 있습니다 :
LC_CTYPE=C LC_COLLATE=C tr -dc 'A-Za-z0-9_!@#$%^&*()+=-'
(여기에서 -
를 끝으로 이동하면 그렇지 않은 경우 )-+
와 같은 범위로 사용됩니다 A-Z
)
그러나 노트는 것을 LC_ALL
변수는 다른 모든 무시 LC_*
와 LANG
변수를. 따라서 LC_ALL
달리 정의되어 있으면 위의 효과가 없습니다. 대신 간단하게 할 수 있습니다 :
LC_ALL=C tr -dc 'A-Za-z0-9_!@#$%^&*()+=-'
이는 오류 메시지의 언어와 같은 다른 요소에 영향을 미치지 만 LC_CTYPE 변경은 이미 오류 메시지의 문제 일 수 있습니다 (예 : C 로케일의 문자 세트로 러시아어 또는 일본어 오류 메시지를 표현할 방법이 없음).
답변
man 페이지 에 따르면 / dev / random은 아마도 당신의 필요에 충분할 것입니다. 아마도 애플은 불필요하기 때문에 / dev / urandom 생성을 중단했을까요?