/ dev / random의 dd가 다른 파일 크기를 제공하는 이유는 무엇입니까?


26

우분투 시스템에서 다음 명령을 실행 중입니다.

dd if=/dev/random of=rand bs=1K count=2

그러나 실행할 때마다 다른 크기의 파일이 생깁니다. 왜 이런거야? 임의의 데이터로 채워진 주어진 크기의 파일을 어떻게 생성 할 수 있습니까?


1
/dev/random엔트로피가 충분하지 않으면 원하는 자릿수를 생성 할 수 없습니다. 그것은 임의의 양의 고품질 psuedo random "randomness"를 모으는 데 시간이 걸립니다 ... /dev/urandom덜 임의적 인 "random"값을 사용하거나 엔트로피 풀을 확인하십시오 (루프에서 필요에 따라 기다리십시오) ...
Peter.O

이 질문 도 참조하십시오 .
Keith Thompson

3
그냥 추가iflag=fullblock
frostschutz

답변:


31

당신은 dd리눅스의 독특한 행동과 리눅스의 독특한 행동의 조합을 관찰하고 /dev/random있습니다. 그건 그렇고, 둘 다 직업에 적합한 도구는 거의 없습니다.

리눅스 /dev/random는 데이터를 아껴서 반환합니다. 의사 난수 생성기의 엔트로피가 매우 빠른 속도로 소멸된다는 가정을 기반으로합니다. 새로운 엔트로피 수집이 느리기 때문에 /dev/random일반적으로 한 번에 몇 바이트 만 포기합니다.

dd테이프 장치에서 작동하도록 고안된 오래된 크 랭키 프로그램입니다. 1kB의 한 블록을 읽도록 지시하면 한 블록을 읽으려고 시도합니다. 읽기가 1024 바이트 미만을 반환하면 터프 해집니다. 그래서 dd if=/dev/random bs=1K count=2두하게 read(2)전화를. 에서 읽는 중이므로 /dev/randomread호출은 일반적으로 사용 가능한 엔트로피에 따라 다양한 숫자로 몇 바이트 만 반환합니다. dd언제 데이터 복사에 적합한가? (또는 read () 및 write () 부분 인 경우)

OS 설치 프로그램 또는 복제기를 설계하지 않는 한 /dev/randomLinux에서는 항상 사용해서는 안됩니다 /dev/urandom. urandom매뉴얼 페이지 다소 오해의 소지가있다; /dev/urandom실제로는 수명이 긴 키를 생성하는 경우에도 암호화에 적합합니다. 유일한 제한 /dev/urandom은 충분한 엔트로피를 제공해야한다는 것입니다. Linux 배포판은 일반적으로 재부팅 사이에 엔트로피를 저장하므로 엔트로피가 충분하지 않은 유일한 시간은 새로 설치하는 것입니다. 엔트로피는 실제적으로 마모되지 않습니다. 자세한 정보 는 / dev / urandom의 랜드가 로그인 키에 대해 안전한가요?를 참조하십시오. 그리고 / dev / random entropy pool을 먹이시겠습니까? .

대부분의 사용은 또는 dd과 같은 도구로 더 잘 표현됩니다 . 2kB의 임의 바이트를 원하면 다음을 실행하십시오.headtail

head -c 2k </dev/urandom >rand

구형 리눅스 커널을 사용하면

dd if=/dev/urandom of=rand bs=1k count=2

/dev/urandom요청한만큼 많은 바이트를 행복하게 반환 했기 때문 입니다. 그러나 이것은 커널 3.16 이후 더 이상 사실이 아니며 이제 32MB로 제한됩니다 .

일반적으로 dd고정 된 수의 바이트를 추출하는 데 사용해야 하고 입력이 일반 파일 또는 블록 장치에서 나오지 않는 경우 바이트 단위로 읽어야 dd bs=1 count=2048합니다.


dd 대신 헤드 사용에 대한 팁을 주셔서 감사합니다. 그래도 원하는 경우 / dev / random을 계속 사용할 수 있습니다. 언급 한대로 / dev / urandom으로 충분할 수도 있지만, 필요한 경우 / dev / random을 사용하는 방법을 아는 것이 좋습니다.
다니엘

3.16 이후 커널에서 /dev/urandom 32m을 반환합니다read() .
mikeserv

또는 POSIX 호환 명령이 필요한 경우 여기에서 트릭을 사용할 수 있습니다. unix.stackexchange.com/a/192114 dd if=/dev/urandom ibs=1k obs=1k | dd bs=1k count=2
Rufflewind

11

에서 man 4 randomRHEL은 5 상자 :

읽을 때 / dev / random 장치는 엔트로피 풀의 추정 된 비트 수의 비트 내에서 임의의 바이트 만 반환합니다.

해당 컴퓨터에서 크기가 213 바이트 인 파일을 얻습니다. 맨 4 랜덤으로 돌아 가기 :

읽을 때, / dev / urandom 장치는 요청 된 바이트 수만큼 리턴합니다.

모든 호출에서 2048 바이트를 얻습니다. dd if=/dev/urandom of=rand bs=1K count=2

차이점은 호출 사이에 기계가 얼마나 많은 엔트로피를 생성하는지에 달려 있다고 결론을 내립니다. dd if=/dev/random ...


실제로 실제 암호화 응용 프로그램에 있지 않으면 @Daniel은 / dev / urandom을 사용해야합니다. 그러나 dd if=/dev/random bs=1K count=2엔트로피 풀이 분명히 배수 될 때 왜 멈추는 지 의아해 합니다. 문서에서 엔트로피가 더 커질 때까지 차단해야하므로 dd현재 풀을 덤프하고 종료하는 대신 파일이 천천히 기록됩니다.
cjc

나도 그 점에 대해 궁금했지만 RHEL, Slackware 13.1 및 최신 아치에서 일관성이 있습니다. RHEL은 x86_64이고 나머지는 32 비트였습니다. 불행히도 dd 문서는 GNU 정보 형식이므로 모든 것을 읽지는 않았습니다.
Bruce Ediger

젠투에서도 일관성이 있습니다.
Matthew Scharley 2019

4
@cjc : read(fd, mybuf, 1024)블로킹 FD 를 호출 하면 기본 장치가 일부 데이터를 반환하자마자 반환 되기 때문 입니다. 읽을 1024 바이트가 있으면이를 반환합니다. 201 바이트 만 있으면 201을 반환합니다. 사용 가능한 0 바이트가 있으면 최소 1 바이트를 사용할 수있을 때까지 차단 된 다음 반환합니다.
워렌 영

@WarrenYoung은 / dev / random에서 읽는 것이 내용을 배수합니까? 나는 그렇게 생각합니다.
Michael Martinez

5

dd데이터를 삭제합니까? ... Gilles 는 다음과 같은 매력적인 질문을 제기했습니다 dd.
dd는 언제 데이터 복사에 적합합니까? (또는 read () 및 write () partial 인 경우)
다음은 해당 질문에서 발췌 한 내용입니다.

    dd를 잘못 생각하는 것은 어렵지 않다. 예를 들어 다음 코드를 사용해보십시오 : **
        yes | dd of=out bs=1024k count=10
    출력 파일의 크기를 확인하십시오 (10MB 미만일 가능성이 있음).


내 의견 (귀하의 질문 끝)을 제외하고는 이와 같은 것이 지켜 보는 것이 가장 중요합니다 ... file에서 바이트를 잡습니다 $trnd. 나는 임의로 임의로 bs = 8을 선택했다

마우스를 움직여 속도를 높이십시오.
내 컴퓨터가 유휴 상태이고 (AFK 및 네트워크 활동 없음) 엔트로피 풀을 사용한 후 1192 바이트 만 수집 하는 데 2 시간 12 분이 걸렸 으며이 시점에서 취소했습니다.

그런 다음 마우스를 계속 움직이면서 동일한 바이트 수를 수집하는 데 1 15 초가 비교적 짧았습니다 .

이것은 엔트로피 수집이 CPU 속도 기반이 아니라 무작위 이벤트 기반이며 내 우분투 시스템이 마우스를 중요한 임의의 요소 중 하나로 사용한다는 것을 분명히 보여줍니다 .

get=2048
trnd=/tmp/$USER.rnd; >"$trnd"
while (( $(wc -c <"$trnd") < $get )) ;do
    dd if=/dev/random bs=8 count=1 2>/dev/null >>"$trnd"
    echo -n "itt: $((i+=1))  ct: "; wc -c <"$trnd"
done
truncate -s $get "$trnd"
echo -e "\nfinal count: "; wc -c <"$trnd"

1

dd되어 설계 차단 - 그것은 일반적으로 귀하의 처분에 가장 좋은 도구 변수 크기의 입력에서 읽기 위해 당신이 할 필요가있는 경우 즉시 때문에 dd현재의 버퍼되지 않습니다 어떤 미래를 읽는다 write() (당신은 매우 명시 적으로 IBS보다 큰 OBS으로 그런 식으로 구성하지 않은 경우) 하지만 것 대신에 write()모든 그것은 즉시 읽고 read()그것을이야 (선택적으로이를 처리) .

다음은 몇 가지 중요한 정의입니다 .

  • ibs=expr
    • 입력 블록 크기를 바이트 단위로 지정하십시오 (기본값은 512) .expr
  • obs=expr
    • 출력 블록 크기를 바이트 단위로 지정하십시오 (기본값 : 512) .expr
  • bs=expr
    • 입력 및 출력 블록 크기를 모두 expr바이트, 대체 ibs=및로 설정하십시오 obs=. 이하 전환 다른 경우 sync, noerrornotrunc지정된 각 입력 블록 짧은 블록 응집하지 않고 단일 블록으로 출력으로 복사한다.

당신이 볼 그래서, 때 ibsobs같은 함께 정의 bs다음 ibs당신도 다음, 특정 경우는 true, 그렇지 않은 경우는 있지만 - 우선 순위를 갖 obs거나 cbs않습니다.

ibs가장 중요한 예는 다음과 같습니다 . /dev/random수영장이 얼마나 빨리 채워 졌는지 추적하려는 경우 이와 같은 작업을 수행 할 수 있습니다 ...

dd "ibs=$size" conv=sync "count=$lmt" \ 
    if=/dev/random of="$somefile"

만큼 if=의 대상이 전혀 읽을 수있는, 그 것이다 항상 있기 때문에, 같은 크기의 출력 파일을 초래할 dd것이다 sync블록이 읽기에 널 (null)에 hronize. 다시 말해, dd read()입력 블록에 대한 s $((size=10)) $((count=5))read()파일이 2 바이트, 8 바이트, 12 바이트, 2 바이트, 4 바이트를 반환하면 다음 과 같이 출력 파일에 dd기록됩니다.

 2 read bytes 8NULs \
 8 read bytes 2NULs \
10 read bytes 0NULs \
 4 read bytes 6NULs \
 4 read bytes 6NULs

... dd기본적으로 지연 되지 않기 때문입니다. 따라서 인스 트림을 추적하고 다른 프로세스의 쓰기를 구분해야하는 경우 dd적합한 도구입니다.

일정한 양의 데이터를 일반 파일에 쓰는 경우 여기에 작성된 다른 진술과 달리이를 dd위해 상당히 쉽게 사용할 수 있지만 하나 이상의 신뢰할 수있는 차단 요소가 필요 합니다.

예를 들어, 다음과 같은 경우 :

{   dd ibs="$size" obs="${size}x$block_factor" |
    dd bs="${size}x$blockfactor" "count=$lmt"
}  <infile >outfile

... 첫 번째 dd는 파이프와 두 번째 파이프 사이 ibs="$size"에 적어도 하나의 obs="${size}x$block_factor"출력 블록 을 채우는 데 필요한만큼의 입력 블록을 버퍼링 write()합니다 dd. 두 번째는 것을이 수단 dd안정적으로 출력을 제한 할 수 count="$lmt"의 모든 때문에 write()첫 번째 차종이 난 일치합니다들 / O 블록 크기 - 에 관계없이 얼마나 많은 read()첫 번째의 dd수행해야합니다 그래서 그것을 확인합니다.

그리고 '당신이 사용할 수있는 방법은 다음 dd수학의 조금에 - 안정적으로 읽을 파이프 나 특수 파일의 다른 유형.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.