IMAP 서버에서 얻은 utf7 파일 이름을 올바르게 디코딩하는 방법

IMAP 서버에서 얻은 utf7 파일 이름을 올바르게 디코딩하는 방법

IMAP 서버에서 일부 디렉토리를 다운로드했습니다.

예:

$ find . -maxdepth 1
.
./&BCEEPwQwBDw-
./&BCMENAQwBDsENQQ9BD0ESwQ1-
./inbox
./&BCcENQRABD0EPgQyBDgEOgQ4-
./&BB4EQgQ,BEAEMAQyBDsENQQ9BD0ESwQ1-
./&BBgEQQRFBD4ENARPBEkEOAQ1-
./Archive

이는 UTF-7로 인코딩된 키릴 문자 이름입니다. 내가 아는 한, UTF-7 인코딩 단위는 모두 127 미만의 유효한 유니코드 코드 포인트이며 유효한 ASCII이기도 합니다. 즉, 원하는 곳 어디에서나 복사하고, 붙여넣고, 파이프하고, 고양이를 표시할 수 있습니다.

변환을 해보자:

$ ls | iconv -f utf7 -t utf8
&BB4EQgQ,BEAEMAQyBDsENQQ9BD0ESwQ1-/
&BBgEQQRFBD4ENARPBEkEOAQ1-/
&BCEEPwQwBDw-/
&BCMENAQwBDsENQQ9BD0ESwQ1-/
&BCcENQRABD0EPgQyBDgEOgQ4-/
Archive/
inbox/

와트? 효과가 없나요? iconv -lutf-7 및 utf-8을 나열하십시오.

뭐가 문제 야?

답변1

키릴 문자를 UTF8에서 UTF7로 변환하는 빠른 테스트

echo 'Here we go. Це коротке речення' | iconv -f utf-8 -t utf-7
Here we go. +BCYENQ +BDoEPgRABD4EQgQ6BDU +BEAENQRHBDUEPQQ9BE8

하나 읽어보세요UTF7에 대한 설명+인코딩 UTF7 디렉토리 목록에는 각 인코딩 문자열 앞에 가 있어야 한다는 것을 (대략적으로 말하면) 알 수 있습니다 .

이제 보시다시피 추출된 데이터를 다음으로 변환해도 유효한 코드 포인트가 생성되지 않습니다 &.+

echo '&BB4EQgQ,BEAEMAQyBDsENQQ9BD0ESwQ1-/' | tr '&' + | iconv -f utf-7 -t utf-8
От
iconv: (stdin):1:2: cannot convert

&그러나 파일 이름 자체를 사용하는 경우 로 전환하면 유효한 변환을 얻게 됩니다 +.

echo '&BCMENAQwBDsENQQ9BD0ESwQ1-' | tr '&' + | iconv -f utf-7 -t utf-8
Удаленные

답변2

본질적으로 이 질문은 부적절합니다. 문제는 IMAP(ab)이 utf-7을 사용한다는 것입니다. 거의 UTF-7이지만 정확하지는 않습니다. 마지막으로 PHP 문서 주석의 PHP 코드를 사용하여 문제를 해결했습니다.

imap-utf7에 대한 PHP 문서

답변3

IMAP의 수정된 UTF-7과 UTF-8 또는 기타 인코딩 간에 디코딩(또는 인코딩)을 위한 Perl 모듈이 있습니다.인코딩::IMAPUTF7. 따라서 명령줄에서 직접 디코딩하는 것이 매우 쉽습니다.

일반적으로 기본적으로 설치되지 않습니다. Debian 기반 시스템(Ubuntu 등)에 설치하려면:

sudo apt install libencode-imaputf7-perl

또는 MacOS에서는:

cpanp i Encode::IMAPUTF7

Bash 터미널의 현재 디렉터리에 있는 모든 파일이나 폴더의 이름을 UTF-8로 바꾸는 한 줄 예:

find . -depth -name '*&*' | while read x; do new=$(perl -CSA -MEncode::IMAPUTF7 -le 'print Encode::IMAPUTF7::decode(\"IMAP-UTF-7\", shift)' "$x") && mv -v "$x" "$new"; done

또는 가독성을 위해 더 많은 줄로 분할합니다.

find . -depth -name '*&*' \
| while read x; do
    new=$(perl -CSA -MEncode::IMAPUTF7 -le 'print Encode::IMAPUTF7::decode(\"IMAP-UTF-7\", shift)' "$x") \
      && mv -v "$x" "$new";
  done

답변4

최근 GNU 시스템에서는 최소한 iconv하나의 인코딩이 지원됩니다 UTF-7-IMAP. ls개행 문자는 유효한 문자가 아니지만 출력을 전달할 수는 없습니다.

$ ls | iconv -f UTF-7-IMAP
Archiveiconv: illegal input sequence at position 7

사용되면 -c디코딩할 수 없는 문자를 무시합니다.

$ ls | iconv -cf UTF-7-IMAP
ArchiveОтправленныеИсходящиеЧерновикиСпамУдаленныеinbox

또는 각 파일 이름을 개별적으로 제공할 수 있습니다 iconv.

$ for f in *; do printf %s "$f" | iconv -f UTF-7-IMAP; echo; done
Archive
Отправленные
Исходящие
Черновики
Спам
Удаленные
inbox

또는 다음을 수행하십시오.

$ printf '%s&AAo-' * | iconv -f UTF-7-IMAP
Archive
Отправленные
Исходящие
Черновики
Спам
Удаленные
inbox

&AAo-줄 바꿈의 UTF-7-IMAP 인코딩은 어디에 있습니까?

대부분의 프로그래밍 언어에는 iconv(3)표준 인터페이스에 대한 바인딩이 있습니다. 예를 들면 다음과 같습니다 perl.

$ perl -MText::Iconv -le '$c = Text::Iconv->new(qw(UTF-7-IMAP UTF-8));
                          print $c->convert($_) for @ARGV' -- *
Archive
Отправленные
Исходящие
Черновики
Спам
Удаленные
inbox

따라서 perl다음을 사용하여 이러한 파일의 이름을 바꿀 수 있습니다 rename(저는 2.0.1에서 File::Rename을 사용하고 있습니다. 다양한 변형과 ​​버전이 있다는 점에 유의하십시오 rename).

$ rename -n -- '
    use Text::Iconv;
    our $c //= Text::Iconv->new(qw(UTF-7-IMAP UTF-8));
    $_ = $c->convert($_)' *
rename(&BB4EQgQ,BEAEMAQyBDsENQQ9BD0ESwQ1-, Отправленные)
rename(&BBgEQQRFBD4ENARPBEkEOAQ1-, Исходящие)
rename(&BCcENQRABD0EPgQyBDgEOgQ4-, Черновики)
rename(&BCEEPwQwBDw-, Спам)
rename(&BCMENAQwBDsENQQ9BD0ESwQ1-, Удаленные)

관련 정보