본문 바로가기
리눅스

uuencoding

by 다움위키 2023. 12. 23.

uuencoding은 이메일 시스템에서 전송에 대해 이진 데이터를 인코딩에 대해, 1980년 UC Berkeley에서 Mary Ann Horton에 의해 작성된 유닉스 프로그램 uuencodeuudecode에서 기원된 이진-에서-텍스트 인코딩의 한 형식입니다.

이름 "uuencoding"은 "유닉스-에서-유닉스 인코딩"에서 파생되었습니다. 즉, 유닉스 파일을 하나의 유닉스 시스템에서 또 다른 유닉스 시스템으로 전송하지만 중간 링크가 모두 유닉스 시스템이라는 보장은 없이 전송하기 위해 안정한 인코딩을 사용하는 아이디어입니다. 이메일 메시지가 다른 문자 집합을 가진 컴퓨터를 통해 또는 컴퓨터로 전달되거나 8-비트 클린이 아닌 전송을 통해 전달되거나, 8-비트 클린이 아닌 프로그램에서 처리될 수 있으므로, 이메일을 통해 이진 파일을 전달하는 것은 파일이 손상되는 원인이 될 수 있습니다. 그러한 데이터를 대부분의 문자 집합에 공통적인 문자 부분집합으로 인코딩함으로써, 그러한 데이터 파일의 인코딩된 형식이 "번역"되거나 손상될 가능성이 거의 없었고, 따라서 대상에서 손상되지 않고 변경되지 않고 도착할 것입니다. 프로그램 uudecodeuuencode의 효과를 반대로 하여, 원본 바이너리 파일을 정확하게 다시 만듭니다. uuencode/decode는 바이너리 (및 특히 압축된) 파일을 이메일로 보내고 유즈넷 뉴스그룹, 등에 게시하는 데 널리 사용되었습니다.

그것은 이제 MIMEyEnc에 의해 크게 대체되었습니다. MIME과 함께, uuencoded일 수 있는 파일이 대신 base64 인코딩으로 전송됩니다.

Encoded format

uuencoded 파일은 다음 형식의 헤더 줄로 시작합니다:

begin <mode> <file><newline>

<mode>는 세 개의 팔진 자릿수 (예를 들어, 644, 744)로 파일의 유닉스 파일 허가권입니다. 이것은 전형적으로 오직 유닉스-계열 운영 시스템에서 중요합니다.

<file>은 바이너리 데이터를 다시 생성할 때 사용될 파일 이름입니다.

<newline>은 각 줄을 종료하기 위해 사용되는 줄 바꿈 문자를 나타냅니다.

각 데이터 줄은 다음 형식을 사용합니다:

<length character><formatted characters><newline>

<length character>는 해당 줄에서 인코딩된 데이터 바이트 수를 나타내는 문자입니다. 이것은 실제 바이트 카운트에 32를 추가함으로써 결정된 ASCII 문자입니다. 단, 영 바이트를 의미하는 억음 악센트 "`" (ASCII 코드 96)만 제외합니다. 마지막을 제외한 모든 데이터 줄 (데이터 길이가 45로 나눌 수 없으면)은 45 바이트의 인코딩된 데이터 (인코딩 후 60 문자)를 가집니다. 그러므로, 대부분의 길이 값은 'M' (32 + 45 = ASCII 코드 77 또는 "M")입니다.

<formatted characters>는 인코딩된 문자입니다. 실제 구현에 대한 자세한 내용에 대해 아래의 포맷 메커니즘을 참조하십시오.

파일은 두 줄로 끝납니다:

`<newline>
end<newline>

마지막에서 두 번째 줄은 역시 영 바이트를 의미하는 억음 악센트를 갖는 줄 길이를 나타내는 문자입니다.

완전한 파일로서, 오직 Cat 문자만 포함하는 cat.txt라는 이름의 일반 텍스트 파일에 대한 uuencoded 출력은 다음입니다:

begin 644 cat.txt
#0V%T
`
end

시작 줄은 표준 uuencode 헤더입니다; '#'은 해당 줄이 3개의 문자를 인코딩함을 나타냅니다; 마지막 두 줄은 모든 uuencoded 파일의 끝에 나타납니다.

Formatting mechanism

uuencoding의 메커니즘은 3바이트마다 다음을 반복하여, 인쇄 가능한 4개의 문자로 인코딩하며, 각 문자는 radix-64 숫자 자릿수를 나타냅니다:

  1. 소스에서 3바이트로 시작하여 총 24비트입니다.
  2. 4개의 6-비트 그룹으로 나뉘며, 각각은 0에서 63 사이의 값을 나타냅니다: 비트 (00-05), (06-11), (12-17) 및 (18-23).
  3. 각 값에 32를 더합니다. 32의 덧셈과 함께, 이것은 가능한 결과가 32 (" " 스페이스)와 95("_" 밑줄) 사이가 될 수 있음을 의미합니다. "특수 문자"로 96 ("`" 억음 악센트)은 이 범위의 논리적 확장입니다. 스페이스 문자가 0 값에 대한 인코딩으로 문서화되어 있음에도 불구하고, GNU sharutils와 같은 구현은 실제로 결코 스페이스르 사용하지 않고 파일 본문에서 0을 인코딩하기 위해 억음 악센트 문자를 사용합니다.
  4. 이들 숫자의 동등한 ASCII를 출력합니다.

만약 소스 길이가 3으로 나눌 수 없으면, 마지막 4-바이트 섹션은 깔끔하게 나뉠 수 있도록 패딩 바이트를 포함할 것입니다. 이들 바이트는 디코더가 파일에 원하지 않는 문자를 덧붙이지 않도록 줄의 <length character>에서 뺍니다.

uudecoding은 위의 것과 반대로, 각 문자의 ASCII 코드에서 32를 빼서 (억음 악센트 사용을 설명하기 위해 모듈로 64) 6-비트 값을 얻고, 4개의 6-비트 그룹을 연쇄하여 24비트를 얻고, 그런-다음 3바이트를 출력합니다.

인코딩 과정은 "Cat"에 대한 위의 인코딩의 파생물을 보여주는 이 테이블에 의해 시연됩니다.

원래 문자 C a t
원래 ASCII, 십진수 67 97 116
ASCII, 이진수 0 1 0 0 0 0 1 1 0 1 1 0 0 0 0 1 0 1 1 1 0 1 0 0
새로운 십진 값 16 54 5 52
+32 48 86 37 84
Uuencoded 문자 0 V % T

uuencode table

다음 테이블은 변환 과정 동안 얻은 6-비트 필드의 10진수 값과 해당하는 ASCII 문자 출력 코드와 문자의 변환을 보여줍니다.

일부 인코더는 억음 악센트 ("`", 코드 96) 대신 스페이스 (코드 32)을 생성할 수 있지만 일부 디코더는 스페이스를 포함하는 데이터 디코딩을 거부할 수 있음을 주목하십시오.     

여섯 비트 ASCII
코드
ASCII
문자
  여섯비트 ASCII
코드
ASCII
문자
  여섯비트 ASCII
코드
ASCII
문자
  여섯비트 ASCII코드 ASCII문자   여섯비트 ASCII코드 ASCII문자   여섯비트 ASCII코드 ASCII문자   여섯비트 ASCII코드 ASCII문자
00 96 `   10 42 *   20 52 4   30 62 >   40 72 H   50 82 R   60 92 \
01 33 !   11 43 +   21 53 5   31 63 ?   41 73 I   51 83 S   61 93 ]
02 34 "   12 44 ,   22 54 6   32 64 @   42 74 J   52 84 T   62 94 ^
03 35 #   13 45 -   23 55 7   33 65 A   43 75 K   53 85 U   63 95 _
04 36 $   14 46 .   24 56 8   34 66 B   44 76 L   54 86 V        
05 37 %   15 47 /   25 57 9   35 67 C   45 77 M   55 87 W        
06 38 &   16 48 0   26 58 :   36 68 D   46 78 N   56 88 X        
07 39 '   17 49 1   27 59 ;   37 69 E   47 79 O   57 89 Y        
08 40 (   18 50 2   28 60 <   38 70 F   48 80 P   58 90 Z        
09 41 )   19 51 3   29 61 =   39 71 G   49 81 Q   59 91 [        

Example

다음은 한 줄의 텍스트 파일을 uuencoding하는 예제입니다. 이 예제에서, %0D캐리지 리턴 (CR)에 대한 바이트 표현이고, %0A줄 바꿈 (LF)에 대한 바이트 표현입니다.

file

File Name = wikipedia-url.txt
File Contents = http://www.wikipedia.org%0D%0A

uuencoding

begin 644 wikipedia-url.txt
::'1T<#HO+W=W=RYW:6MI<&5D:6$N;W)G#0H`
`
end

Forks (file, resource)

유닉스는 전통적으로 파일 데이터가 저장되는 단일 포크를 가집니다. 어쨌든, 일부 파일 시스템은 단일 파일과 결합된 다중 포크를 지원합니다. 예를 들어, 클래식 Mac OS HFS는 데이터 포크와 리소스 포크를 지원했습니다. Mac OS HFS+는 Microsoft Windows NTFS 대안적인 데이터 스트림과 마찬가지로 다중 포크를 지원합니다. 대부분의 uucoding 도구는 오직 인코딩/디코딩할 때 정보 손실을 초래할 수 있는 주요 데이터 포크에서 데이터를 처리할 것입니다 (예를 들어, Windows NTFS 파일 주석은 다른 포크에 보관됩니다). 일부 도구 (예를 들어, 클래식 Mac OS 응용 프로그램 UUTool)는 다른 포크를 하나의 파일로 연쇄하고 파일 이름에 의해 그것들을 구분함으로써 문제를 해결했습니다.

Relation to xxencode, Base64, and Ascii85

제한된 문자의 범위에도 불구하고, uuencoded 데이터는 때때로 EBCDIC와 같은 비-ASCII 문자 집합을 사용하는 특정 컴퓨터를 통과할 때 손상됩니다. 그 문제를 해결하기 위한 한 가지 시도는 오직 알파벳-숫자 문자와 더하기 및 빼기 기호를 사용하는 xxencode 형식이었습니다. 오늘날 더 공통적인 것은 ASCII 32–95와 달리 알파벳-숫자-전용의 같은 개념을 기반으로 하는 Base64 형식입니다. 세 가지 형식 모두는 그들의 입력 테이터를 나타내기 위해 6비트 (64개의 다른 문자)를 사용합니다.

Base64는 uuencode 프로그램에 의해 생성될 수도 있고 실제 문자 번역을 제외하고 형식에서 유사합니다:

그 헤더는 다음으로 변경됩니다:

begin-base64 <mode> <file>

트레일러가 됩니다:

====

그리고 사이의 줄은 다음에서 선택한 문자로 인코딩됩니다:

ABCDEFGHIJKLMNOP
QRSTUVWXYZabcdef
ghijklmnopqrstuv
wxyz0123456789+/

또 다른 대안은 4개의 이진 문자를 5개의 ASCII 문자로 인코딩하는 Ascii85입니다. Ascii85는 PostScriptPDF 형식에서 사용됩니다.

Disadvantages

uuencoding은 미리-형식-지정된 3바이트를 취하고 그것들을 4바이트로 변환하고 역시 시작/종료 태그, 파일이름, 및 구분 기호를 추가합니다. 이것은 소스 단독에 비해 적어도 33%의 데이터 오버헤드를 추가하지만, 이것은 파일을 uuencoding하기 전에 그것을 압축함으로써 적어도 어느 정도 보상될 수 있습니다.

Support in Python

Python 언어는 코덱 "uu"와 함께 codecs 모듈을 사용하여 uuencoding을 지원합니다:

파이션 2에 대해 (2020년 1월 1일 더 이상 사용하지 않음):

$ python -c 'print "Cat".encode("uu")'
begin 666 <data>
#0V%T

end

$

파이션 3에 대해 코덱 모듈이 가져오게 되고 직접 사용되는 곳에서:

$ python3 -c "from codecs import encode;print(encode(b'Cat', 'uu'))"
b'begin 666 <data>\n#0V%T\n \nend\n'
$

Support in Perl

Perl 언어는 기본적으로 "u" 형식 문자열과 함께 pack() 및 unpack() 연산자를 사용하여 uuencoding을 지원합니다:

$ perl -e 'print pack("u","Cat")'
#0V%T

unpack을 갖는 base64를 디코딩하는 것은 역시 마찬가지로 문자를 번역함으로써 수행될 수 있습니다:

$ perl -e '$a="Q2F0"; $a=~tr#A-Za-z0-9+/\.\_##cd; # remove non-base64 chars
> $a=~tr#A-Za-z0-9+/# -_#; # translate sets
> print unpack("u",pack("C",32+int(length($1)*6 / 8)) . $1) while($a=~s/(.{60}|.+)//);'
Cat

External links