[regex] Base64 데이터를 구문 분석하거나 유효성을 검사하는 RegEx

RegEx를 사용하여 Base64 데이터의 유효성을 검사하거나 삭제하는 것이 가능합니까? 그것은 간단한 질문이지만이 질문을 유도하는 요인은 그것을 어렵게 만드는 것입니다.

RFC 사양을 따르기 위해 입력 데이터에 완전히 의존 할 수없는 Base64 디코더가 있습니다. 그래서 내가 직면하는 문제는 아마도 Base64 데이터와 같은 문제이며 78로 나뉘 지 않을 수도 있습니다 (78이라고 생각합니다. RFC를 다시 확인해야하므로 정확한 숫자가 잘못되었다고 생각하지 마십시오). 라인 또는 라인이 CRLF로 끝나지 않을 수 있습니다. CR 또는 LF 만 있거나 둘 다 없을 수도 있습니다.

그래서 나는 그런 형식의 Base64 데이터를 파싱하는 데 엄청난 시간을 보냈습니다. 이로 인해 다음과 같은 예는 안정적으로 디코딩 할 수 없게됩니다. 간결성을 위해 부분 MIME 헤더 만 표시합니다.

Content-Transfer-Encoding: base64

VGhpcyBpcyBzaW1wbGUgQVNDSUkgQmFzZTY0IGZvciBTdGFja092ZXJmbG93IGV4YW1wbGUu

좋습니다. 파싱은 문제가되지 않으며 우리가 기대하는 결과입니다. 그리고 99 %의 경우, 버퍼의 각 문자가 유효한 base64 문자인지 확인하기 위해 코드를 사용하면 완벽하게 작동합니다. 그러나 다음 예제에서는 렌치를 믹스에 넣습니다.

Content-Transfer-Encoding: base64

http://www.stackoverflow.com
VGhpcyBpcyBzaW1wbGUgQVNDSUkgQmFzZTY0IGZvciBTdGFja092ZXJmbG93IGV4YW1wbGUu

이 버전은 일부 바이러스 및 일부 메일 독자가 모든 비용을 들여 마임을 구문 분석하려는 다른 것들에서 본 Base64 인코딩 버전입니다. 당신이 원한다면.

My Base64 디코더는 두 번째 예제를 다음 데이터 스트림으로 디코딩합니다. 여기서 명심하세요. 원본 스트림은 모두 ASCII 데이터입니다!

[0x]86DB69FFFC30C2CB5A724A2F7AB7E5A307289951A1A5CC81A5CC81CDA5B5C1B19481054D0D
2524810985CD94D8D08199BDC8814DD1858DAD3DD995C999B1BDDC8195E1B585C1B194B8

누구나 한 번에 두 가지 문제를 해결할 수있는 좋은 방법이 있습니까? 다른 규칙이 적용된 데이터에 대해 두 가지 변환을 수행하고 결과를 비교하는 것 외에는 가능할지 모르겠습니다. 그러나 그러한 접근 방식을 취했다면 어떤 결과물을 신뢰합니까? ASCII 휴리스틱 스가 최상의 솔루션 에 관한 것 같지만 ,이 코드가 실제로 관여하는 바이러스 스캐너만큼 복잡한 것에 얼마나 더 많은 코드, 실행 시간 및 복잡성이 추가 될까요? 허용되는 Base64와 그렇지 않은 것을 학습하기 위해 휴리스틱 엔진을 어떻게 훈련 시키겠습니까?


최신 정보:

이 질문이 계속해서 얻는 조회수를 고려하여 지금까지 C # 애플리케이션에서 3 년 동안 사용해 온 간단한 RegEx를 수십만 건의 트랜잭션으로 게시하기로 결정했습니다. 솔직히 검보 님 의 답변 이 가장 마음에 들어서 제가 선택한 답변으로 꼽았습니다. 그러나 C #을 사용하는 사람에게 문자열 또는 byte []에 유효한 Base64 데이터가 포함되어 있는지 여부를 감지하는 매우 빠른 방법을 찾고있는 사람에게는 다음이 매우 잘 작동한다는 것을 알았습니다.

[^-A-Za-z0-9+/=]|=[^=]|={3,}$

그리고 예, 이것은 올바른 형식의 RFC1341 메시지가 아닌 Base64 데이터 의 STRING 을위한 것 입니다. 따라서 이러한 유형의 데이터를 처리하는 경우 위의 RegEx를 사용하기 전에이를 고려하십시오. 당신은 Base16, Base32, 기수 또는 다른 목적 (URL을 파일 이름, XML 인코딩 등)도 Base64로 처리하는 경우,되어 매우 당신이 읽을 것을 권장 RFC4648을 것을 검보는 당신이 잘 할 필요가로서 그의 대답에 언급 이 질문 / 답변 세트의 제안을 사용하기 전에 구현에서 사용하는 문자 세트와 종결자를 알고 있어야합니다.



답변

로부터 4648 RFC :

데이터의 기본 인코딩은 레거시 이유로 US-ASCII 데이터로 제한되는 환경에서 데이터를 저장하거나 전송하기 위해 많은 상황에서 사용됩니다.

따라서 데이터가 위험한 것으로 간주되어야하는 경우 인코딩 된 데이터의 사용 목적에 따라 다릅니다.

그러나 Base64로 인코딩 된 단어와 일치하는 정규식을 찾고 있다면 다음을 사용할 수 있습니다.

^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$


답변

^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$

이것은 좋지만 빈 문자열과 일치합니다.

이것은 빈 문자열과 일치하지 않습니다.

^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{4})$


답변

둘은 ” : “도 아니고 “이 . 난 당신이 명확하게 버릴 수 있다고 생각하므로, 유효 Base64로에 표시됩니다” http://www.stackoverflow.com라인. Perl에서는 다음과 같이 말하십시오.

my $sanitized_str = join q{}, grep {!/[^A-Za-z0-9+\/=]/} split /\n/, $str;

say decode_base64($sanitized_str);

당신이 원하는 것일 수 있습니다. 그것은 생성합니다

이것은 StackOverflow 예제를위한 간단한 ASCII Base64입니다.


답변

지금까지 찾을 수있는 최고의 정규식이 여기에 있습니다.
https://www.npmjs.com/package/base64-regex입니다.

현재 버전에있는 것은 다음과 같습니다.

module.exports = function (opts) {
  opts = opts || {};
  var regex = '(?:[A-Za-z0-9+\/]{4}\\n?)*(?:[A-Za-z0-9+\/]{2}==|[A-Za-z0-9+\/]{3}=)';

  return opts.exact ? new RegExp('(?:^' + regex + '$)') :
                    new RegExp('(?:^|\\s)' + regex, 'g');
};


답변

base64 이미지의 유효성을 검사 하기 위해이 정규식을 사용할 수 있습니다.

/ ^ data : image / (?: gif | png | jpeg | bmp | webp) (? :; charset = utf-8) ?; base64, (? : [A-Za-z0-9] | [+ /] ) + = {0,2}

  private validBase64Image(base64Image: string): boolean {
    const regex = /^data:image\/(?:gif|png|jpeg|bmp|webp)(?:;charset=utf-8)?;base64,(?:[A-Za-z0-9]|[+/])+={0,2}/;
    return base64Image && regex.test(base64Image);
  }


답변

다음은 대체 정규식입니다.

^(?=(.{4})*$)[A-Za-z0-9+/]*={0,2}$

다음 조건을 충족합니다.

  • 문자열 길이는 4의 배수 여야합니다. (?=^(.{4})*$)
  • 내용은 영숫자 또는 + 또는 /-여야합니다. [A-Za-z0-9+/]*
  • 끝에 최대 2 개의 패딩 (=) 문자를 사용할 수 있습니다. ={0,2}
  • 빈 문자열을 허용합니다.


답변