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

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

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

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

그러나 실행할 때마다 크기가 다른 파일이 나타납니다. 왜 이런거야? 임의의 데이터로 채워진 주어진 크기의 파일을 생성하는 방법은 무엇입니까?

답변1

당신이 관찰하고 있는 특별한 행동은 ddLinux의 특별한 행동의 조합입니다 /dev/random. 그건 그렇고, 어느 쪽도 작업에 적합한 도구는 아닙니다.

Linux는 /dev/random데이터를 거의 반환하지 않습니다. 이는 의사 난수 생성기의 엔트로피가 매우 빠르게 사라진다는 가정에 기초합니다. 새로운 엔트로피는 천천히 수집되므로 /dev/random일반적으로 한 번에 몇 바이트만 제공됩니다.

dd원래 테이프 장치에서 실행되도록 설계된 오래되고 기발한 프로그램입니다. 1kB 블록을 읽으라고 지시하면 블록 읽기를 시도합니다. 읽기에서 1024바이트 미만을 반환하면 그게 전부입니다. 그래서 두 번이나 전화를 dd if=/dev/random bs=1K count=2걸었습니다 . read(2)에서 읽기 때문에 /dev/random이 두 read호출은 일반적으로 사용 가능한 엔트로피에 따라 달라지는 몇 바이트만 반환합니다. 당신은 또한 볼 수 있습니다dd는 언제 데이터 복사에 적합합니까? (또는 read() 및 write()가 부분적인 경우)

운영 체제 설치 프로그램이나 복제 프로그램을 설계하지 않는 한 /dev/randomLinux에서는 절대 사용 해서는 안 됩니다 /dev/urandom. 매뉴얼 urandom페이지는 약간 오해의 소지가 있습니다. /dev/urandom실제로는 암호화에 작동하며 장기 키를 생성할 수도 있습니다. 유일한 제한 /dev/urandom은 충분한 엔트로피를 제공해야 한다는 것입니다. Linux 배포판은 일반적으로 재부팅 사이에 엔트로피를 저장하므로 새로 설치할 때에만 엔트로피가 충분하지 않을 수 있습니다. 사실 엔트로피는 절대 사라지지 않습니다. 더 많은 정보를 원하시면 읽어주세요/dev/urandom의 rand는 로그인 키에 안전합니까?그리고피드 /dev/랜덤 엔트로피 풀?.

의 대부분의 용도는 dd와 같은 도구를 통해 더 잘 표현할 수 있습니다. 2kB의 임의 바이트를 원하면 다음을 실행하십시오.headtail

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

이전 Linux 커널을 사용하면 벗어날 수 있습니다.

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

/dev/urandom요청한 만큼의 바이트를 반환하는 것이 좋기 때문입니다 . 그러나 커널 3.16부터는 더 이상 그렇지 않습니다.이제 32MB로 제한됩니다..

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

답변2

man 4 randomRHEL 5 상자 에서 :

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

해당 컴퓨터에서 파일 크기는 213바이트입니다. 무작위로 Men 4로 돌아가기:

읽을 때 /dev/urandom 장치는 요청된 바이트 수를 반환합니다.

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

내 결론은 차이가 호출 사이에 기계가 생성하는 엔트로피의 양 때문이라는 것입니다.dd if=/dev/random ...

답변3

데이터가 손실되는 이유는 무엇입니까 dd? ...자일스이 흥미로운 질문이 제기되었습니다 dd.
dd는 언제 데이터 복사에 적합합니까? (또는 read() 및 write()가 부분적인 경우)
다음은 질문에서 발췌한 내용입니다.

    *...오류에 대해 dd를 비난하는 것은 어렵지 않습니다. 예를 들어 다음 코드를 시도해 보세요. **
        yes | dd of=out bs=1024k count=10
    그리고 출력 파일의 크기를 확인하세요(아마도 10MB보다 훨씬 작을 것입니다).


귀하의 질문 끝에 있는 내 의견 외에도 이와 같은 내용은 볼만한 가치가 있습니다. 파일의 바이트를 캡처합니다 $trnd. bs=8을 반 임의로 선택했습니다.

마우스를 움직여 속도를 관찰해 보세요.
내 컴퓨터가 유휴 상태일 때(AFK 및 네트워크 활동 없음) 엔트로피 풀을 소진한 후2시간12분수집만 한다1192 화바이트, 그 시점에서 취소했습니다.

그러다가 마우스를 계속 움직이다보니 상대적으로 시간이 덜 걸리더라구요115초동일한 수의 바이트를 수집합니다.

이는 엔트로피 수집이 CPU 속도가 아니라무작위 이벤트기반으로 내 Ubuntu 시스템은 마우스를 다음 중 하나로 사용합니다.중요한무작위 요인.

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"

답변4

dd디자인됨차단용 - 일반적으로 필요한 경우 가변 크기 입력에서 데이터를 읽는 데 사용할 수 있는 가장 좋은 도구입니다.dd현재 읽기는 미래로 버퍼링되지 않기 때문에write() (ibs보다 더 큰 obs로 명시적으로 구성하지 않는 한), 그러나 읽은 모든 내용을 write()즉시 읽습니다.read()(그리고 선택적으로 처리).

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

  • ibs=expr
    • 입력 블록 크기를 바이트 단위로 지정합니다.expr (기본값은 512입니다).
  • obs=expr
    • 출력 블록 크기를 바이트 단위로 지정expr (기본값은 512입니다).
  • bs=expr
    • 입력 및 출력 블록 크기를 다음으로 설정합니다.expr, , ibs=obs=이외의 변환이 지정되지 않은 경우 각 입력 블록은 짧은 블록을 집계하지 않고 단일 블록으로 출력에 복사되어야 합니다.syncnoerrornotrunc

따라서 ibs과 가 obs함께 정의 bs되면 ibs우선순위를 갖습니다. 그러나 그렇지 않은 경우에는 obs또는 중 하나가 우선합니다 cbs.

이것은 가장 중요한 예입니다 ibs. 수영장이 가득 차는 데 걸리는 시간을 추적하고 싶다면 /dev/random다음과 같이 할 수 있습니다.

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

if=대상을 읽을 수 있는 한 ,언제나hronize는 null 값을 읽는 것을 dd방지하므로 동일한 크기의 출력 파일이 생성됩니다 . sync즉, dd read()s가 시간의 입력 청크를 나타내고 파일이 2바이트, 8바이트, 12바이트, 2바이트, 4바이트를 반환하는 $((size=10)) $((count=5))경우 출력 파일은 다음과 유사합니다.read()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"이는 첫 번째 항목에서 생성된 모든 s가 해당 I/O 블록 크기와 일치하므로 두 번째 항목이 출력을 안정적으로 제한할 수 있음을 의미합니다.write()ddddcount="$lmt"write()에도 불구하고read()dd그렇게 하려면 첫 번째 사람이 얼마나 해야 합니까 ?

그리고저것이것은 dd약간의 계산만으로 파이프나 기타 유형의 특수 파일을 안정적으로 읽을 수 있는 방법입니다.

관련 정보