문자열이 Base64로 인코딩되었는지 확인하는 방법


195

Base64로 인코딩 된 문자열을 디코딩 한 다음 데이터베이스에 저장하고 싶습니다. 입력이 Base64로 인코딩되지 않은 경우 오류를 발생시켜야합니다.

문자열이 Base64로 인코딩되었는지 어떻게 확인할 수 있습니까?


왜? 상황은 어떻게 일어날 수 있습니까?
Lorne의 후작

2
어떤 프로그래밍 언어 (및 / 또는) 운영 체제를 지정하지 않더라도 이것은 매우 공개적인 질문입니다
bcarroll

5
문자열에 base64로 인코딩 된 문자열에 유효한 문자 만 포함되어 있는지 확인할 수 있습니다. 문자열이 일부 데이터의 base64로 인코딩 된 버전인지 확인할 수 없습니다. 예를 들어 test1234유효한 base64로 인코딩 된 문자열이며, 디코딩 할 때 약간의 바이트가 생성됩니다. test1234base64로 인코딩 된 문자열이 아닌 응용 프로그램 독립적 인 결론 방법 은 없습니다.
Kinjal Dixit

답변:


249

다음 정규식을 사용하여 문자열이 base64로 인코딩되었는지 여부를 확인할 수 있습니다.

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

base64 인코딩에서 문자 세트는 [A-Z, a-z, 0-9, and + /]입니다. 나머지 길이가 4보다 작 으면 문자열이 '='문자 로 채워집니다 .

^([A-Za-z0-9+/]{4})* 문자열이 0 개 이상의 base64 그룹으로 시작 함을 의미합니다.

([A-Za-z0-9+/]{4}|[A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{2}==)$세 가지 형태 중 하나의 문자열 끝을 의미 [A-Za-z0-9+/]{4}, [A-Za-z0-9+/]{3}=또는 [A-Za-z0-9+/]{2}==.


10
그냥 확인하고 싶었으므로 내 질문에 도움을주십시오.이 정규식이 항상 base64 문자열 만 참조한다는 보장은 무엇입니까 ?? 공백이없는 문자열이 있고 4 자의 배수 인 경우 해당 문자열은 base64 문자열로 간주됩니까 ????
DShah

3
그런 다음 디코딩 할 수있는 유효한 base64 문자열입니다. 최소 길이 제약 조건을 추가 할 수 있습니다. 예를 들어, 4 개 그룹의 0 개 이상의 반복 대신에, 4 개 이상이 필요하다. 그것은 또한 당신의 문제에 달려 있습니다. 사용자가 긴 단어와 순수한 ASCII (하 와이어)가 포함 된 언어로 한 단어를 자주 입력하는 경우 base64가 아닌 입력에 일반적으로 공백, 문장 부호 등이 포함 된 경우보다 오류가 발생하기 쉽습니다.
tripleee

62
이것은 입력 b64로 인코딩 된 값일 수 있지만 입력 실제로 b64로 인코딩 된 값 인지 여부는 나타내지 않습니다 . 다시 말해, abcd일치하지만 반드시 평범한 abcd입력 의 인코딩 된 값을 나타내는 것은 아닙니다
Tzury Bar Yochay

3
빈 문자열과 일치하지 않기 때문에 정규 표현식이 올바르지 않습니다. RFC 4648에 따라 길이가 0 인 이진 데이터의 base64 인코딩입니다.
reddish

5
@Adomas, "pass" 그 바이트의 순서로 디코딩하고, 완벽하게 유효한 base64로 문자열입니다 0xa5, 0xab하고 0x2c. 더 많은 결정이 필요하지 않은 경우 우선 순위 를 버리는 이유는 무엇 입니까?
루이스 콜로라도

52

Java를 사용하는 경우 실제로 commons-codec library를 사용할 수 있습니다.

import org.apache.commons.codec.binary.Base64;

String stringToBeChecked = "...";
boolean isBase64 = Base64.isArrayByteBase64(stringToBeChecked.getBytes());

18
문서에서 : 더 이상 isArrayByteBase64(byte[] arrayOctet)사용되지 않습니다. 1.5 사용 isBase64(byte[])은 2.0에서 제거됩니다.
Avinash R

7
바이트 배열로 직접 변환하는 대신 Base64.isBase64 (String base64)를 사용할 수도 있습니다.
Sasa

5
슬프게도 문서에 따르면 : commons.apache.org/proper/commons-codec/apidocs/org/apache/… : "주어진 문자열을 테스트하여 Base64 알파벳 내에 유효한 문자 만 포함되어 있는지 확인합니다. 현재이 방법은 공백을 다음과 같이 처리합니다. 유효한." 즉,이 방법에는 "공백"또는 숫자 ( "0", "1")와 같은 오 탐지가 있습니다.
Christian Vielma

문자열 Base64.isBase64 (content)
ema

4
이 대답은 주어진 값이므로 Base64로 인코딩 된 값이 아니더라도 stringToBeChecked="some plain text"설정 boolean isBase64=true됩니다. commons-codec-1.4의 소스를 읽으십시오. Base64.isArrayByteBase64()문자열의 각 문자가 Base64 인코딩에 대해 유효하며 공백을 허용하는지 확인하십시오.
Brad

49

잘 할 수 있습니다 :

  • 길이가 4 자의 배수인지 확인하십시오
  • 모든 문자가 세트 AZ, az, 0-9, + 및 /에 있는지 확인하십시오. 끝의 패딩을 제외하고 0, 1 또는 2 '='문자입니다.

base64 될 것으로 기대한다면 플랫폼에서 사용 가능한 라이브러리를 사용 하여 바이트 배열로 디코딩 하려고 시도 할 수 있습니다. 유효한 base 64가 아닌 경우 예외가 발생합니다. 플랫폼에 따라 다릅니다. 물론이야.


파싱은 적어도 디코딩 된 바이트 배열을위한 메모리가 필요하다는 점에서 검증과 다릅니다. 따라서 어떤 경우에는 가장 효과적인 방법이 아닙니다.
Victor Yarema

1
@VictorYarema : 유효성 검사 전용 접근법 (글 머리 기호)과 구문 분석 접근법 (글 머리 기호 후)을 모두 제안했습니다.
Jon Skeet

16

Java 8 부터는 java.util.Base64 를 사용 하여 문자열을 시도하고 디코딩 할 수 있습니다 .

String someString = "...";
Base64.Decoder decoder = Base64.getDecoder();

try {
    decoder.decode(someString);
} catch(IllegalArgumentException iae) {
    // That string wasn't valid.
}

3
그렇습니다. 옵션이지만, catch는 Java에서 상당히 비싼 작업이라는 것을 잊지 마십시오
panser

2
더 이상 그렇지 않습니다. 예외 처리가 꽤 잘 수행됩니다. Java Regex가 매우 느리다는 것을 잊지 마십시오. 내 말은 : 정말 느려! 실제로 Base64를 디코딩하고 위의 Regex와 문자열을 일치시키는 대신 작동하지 않는지 확인하는 것이 더 빠릅니다. 나는 거친 테스트를했고 Java Regex 일치는 디코딩에서 최종 예외를 잡는 것보다 약 6 배 느립니다 (!!).
Sven Döring 2016 년

더 많은 테스트 실행으로 실제로 11 배 느려집니다. 이제 자바에서 더 나은 Regex 구현을위한 시간입니다. Java에서 Nashorn JavaScript 엔진을 사용한 정규식 검사조차도 훨씬 빠릅니다. 믿을 수 없는. 또한 JavaScript Regex (Nashorn 포함)가 훨씬 강력합니다.
Sven Döring 2016 년

3
Java 8 대신 Java 11을 사용하면 정규식 검사가 22 배 느려집니다. 🤦 (Base64 디코딩이 빨라 졌기 때문에)
Sven Döring

15

PHP5에 대해 이것을 시도하십시오

//where $json is some data that can be base64 encoded
$json=some_data;

//this will check whether data is base64 encoded or not
if (base64_decode($json, true) == true)
{          
   echo "base64 encoded";          
}
else 
{
   echo "not base64 encoded"; 
}

PHP7에 이것을 사용하십시오

 //$string parameter can be base64 encoded or not

function is_base64_encoded($string){
 //this will check if $string is base64 encoded and return true, if it is.
 if (base64_decode($string, true) !== false){          
   return true;        
 }else{
   return false;
 }
}

1
이것은 어떤 언어입니까? 질문은 언어를 언급하지 않고 요청되었습니다
Ozkan

이 작동하지 않습니다. 문서를 읽으십시오 Returns FALSE if input contains character from outside the base64 alphabet. base64_decode
Aley

1
어떻게? 입력에 외부 문자가 포함되어 있으면 base64가 아닙니다.
Suneel Kumar

7
var base64Rejex = /^(?:[A-Z0-9+\/]{4})*(?:[A-Z0-9+\/]{2}==|[A-Z0-9+\/]{3}=|[A-Z0-9+\/]{4})$/i;
var isBase64Valid = base64Rejex.test(base64Data); // base64Data is the base64 string

if (isBase64Valid) {
    // true if base64 formate
    console.log('It is base64');
} else {
    // false if not in base64 formate
    console.log('it is not in base64');
}

5

확인 경우 문자열의 길이가 Aftwerwards가 있는지 확인하기 위해 정규식을 사용하는 4의 배수 인 모든 문자 문자열을 base64로 문자는가.

\A[a-zA-Z\d\/+]+={,2}\z

사용하는 라이브러리가 줄당 76 개의 최대 문자 규칙을 준수하는 방법으로 개행을 추가하는 경우 빈 문자열로 바꾸십시오.


언급 된 링크는 404를 보여줍니다. 확인하고 업데이트하십시오.
Ankur

@AnkurKumar 미안하지만 사람들이 URL이 좋지 않은 경우 이런 일이 발생합니다. 항상 변경됩니다. 어디로 옮겼는지 모르겠습니다. Google을 통해 다른 유용한 자료를 찾으시기 바랍니다
Yaw Boakye

항상 web.archive.org에서 오래된 페이지를 얻을 수 있습니다. 여기에 원래 URL이 있습니다. web.archive.org/web/20120919035911/http://… 또는 여기에 텍스트를 게시했습니다 : gist.github.com/mika76/d09e2b65159e435e7a4cc5b0299c3e84
Mladen Mihajlovic

4

Base64 에는 많은 변형이 있으므로 문자열 이 처리 할 가변 과 유사한 지 확인하는 것이 좋습니다. 따라서, 인덱스 및 패딩 문자에 대한 아래의 정규식을 조정해야 할 수도 있습니다 (즉 +, /, =).

class String
  def resembles_base64?
    self.length % 4 == 0 && self =~ /^[A-Za-z0-9+\/=]+\Z/
  end
end

용법:

raise 'the string does not resemble Base64' unless my_string.resembles_base64?

3

이 시도:

public void checkForEncode(String string) {
    String pattern = "^([A-Za-z0-9+/]{4})*([A-Za-z0-9+/]{4}|[A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{2}==)$";
    Pattern r = Pattern.compile(pattern);
    Matcher m = r.matcher(string);
    if (m.find()) {
        System.out.println("true");
    } else {
        System.out.println("false");
    }
}

3

문자열이 base64로 인코딩되어 있는지 확인할 수 없습니다. 해당 문자열이 base64로 인코딩 된 문자열 형식 인 경우에만 유효성을 검사 할 수 있습니다. 이는 base64 인코딩으로 생성 된 문자열 일 수 있음을 의미합니다 (정규 표현식에 대해 문자열의 유효성을 검사하거나 라이브러리를 사용할 수 있는지 확인하기 위해 이 질문에 대한 다른 답변은 이것을 확인하는 좋은 방법을 제공하므로 자세한 내용은 다루지 않겠습니다).

예를 들어 string flow은 유효한 base64로 인코딩 된 문자열입니다. 그러나 단순한 문자열 flow인지 영어 단어 인지 또는 기본 64 인코딩 문자열인지 알 수 없습니다.~Z0


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

이 정규 표현식은 레일에서 응용 프로그램의 base64를 식별하는 데 도움이되었지만 한 가지 문제 만있었습니다. 문자열 "errorDescripcion"을 인식하고 오류를 생성하여 문자열의 길이 만 확인하는 것입니다.


위의 정규식 /^.....$/.match(my_string)은 'Unmatched
closed

그리고 'char 클래스의 조기 종료 : / ^ (([A-Za-z0-9 + /'구문 오류
james2611nov

모든 / 문자 앞에 \를 추가하여 고치지 마십시오.
james2611nov

errorDescription유효한 base64 문자열이며 바이트의 이진 시퀀스 (16 진수)로 디코딩합니다 7a ba e8 ac 37 ac 72 b8 a9 b6 2a 27.
루이스 콜로라도

base64로 인코딩 된 문자열을 확인하는 데 완벽했습니다.
Deepak Lakhara

1

이것은 파이썬에서 작동합니다.

import base64

def IsBase64(str):
    try:
        base64.b64decode(str)
        return True
    except Exception as e:
        return False

if IsBase64("ABC"):
    print("ABC is Base64-encoded and its result after decoding is: " + str(base64.b64decode("ABC")).replace("b'", "").replace("'", ""))
else:
    print("ABC is NOT Base64-encoded.")

if IsBase64("QUJD"):
    print("QUJD is Base64-encoded and its result after decoding is: " + str(base64.b64decode("QUJD")).replace("b'", "").replace("'", ""))
else:
    print("QUJD is NOT Base64-encoded.")

요약 : Base64로 인코딩 된 경우 true를IsBase64("string here") 반환 하고 Base64로 인코딩되지 않은 경우 false를 반환합니다 .string herestring here


1

C # 이것은 훌륭합니다 :

static readonly Regex _base64RegexPattern = new Regex(BASE64_REGEX_STRING, RegexOptions.Compiled);

private const String BASE64_REGEX_STRING = @"^[a-zA-Z0-9\+/]*={0,3}$";

private static bool IsBase64(this String base64String)
{
    var rs = (!string.IsNullOrEmpty(base64String) && !string.IsNullOrWhiteSpace(base64String) && base64String.Length != 0 && base64String.Length % 4 == 0 && !base64String.Contains(" ") && !base64String.Contains("\t") && !base64String.Contains("\r") && !base64String.Contains("\n")) && (base64String.Length % 4 == 0 && _base64RegexPattern.Match(base64String, 0).Success);
    return rs;
}

1
Console.WriteLine("test".IsBase64()); // true
Langdon

2
문제를 해결하기 위해 프로그래밍 언어를 전환하도록 권장하는 것은 일반적으로 올바른 응답이 아닙니다.
루이스 콜로라도

0

시스템의 문자열에 특정 제한이나 식별이있는 경우를 제외하고 문자열과 base64로 인코딩 된 방법은 없습니다.


0

이 스 니펫은 원본 컨텐츠의 길이 (예 : 체크섬)를 알고있을 때 유용 할 수 있습니다. 인코딩 된 양식의 길이가 올바른지 확인합니다.

public static boolean isValidBase64( final int initialLength, final String string ) {
  final int padding ;
  final String regexEnd ;
  switch( ( initialLength ) % 3 ) {
    case 1 :
      padding = 2 ;
      regexEnd = "==" ;
      break ;
    case 2 :
      padding = 1 ;
      regexEnd = "=" ;
      break ;
    default :
      padding = 0 ;
      regexEnd = "" ;
  }
  final int encodedLength = ( ( ( initialLength / 3 ) + ( padding > 0 ? 1 : 0 ) ) * 4 ) ;
  final String regex = "[a-zA-Z0-9/\\+]{" + ( encodedLength - padding ) + "}" + regexEnd ;
  return Pattern.compile( regex ).matcher( string ).matches() ;
}

0

RegEx가 작동하지 않고 원래 문자열의 형식 스타일을 알고 있으면이 형식을 정규식으로 지정하여 논리를 되돌릴 수 있습니다.

예를 들어 base64로 인코딩 된 xml 파일로 작업하고 파일에 유효한 xml 마크 업이 있는지 확인하십시오. 내가 추측 할 수 없다면 base64로 디코딩 된 것입니다. 이것은 매우 역동적이지 않지만 작은 응용 프로그램에는 잘 작동합니다.


0

이것은 파이썬에서 작동합니다.

def is_base64(string):
    if len(string) % 4 == 0 and re.test('^[A-Za-z0-9+\/=]+\Z', string):
        return(True)
    else:
        return(False)

0

이전에 언급 한 정규 표현식을 사용하여 시도하십시오.

String regex = "^([A-Za-z0-9+/]{4})*([A-Za-z0-9+/]{4}|[A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{2}==)$";
if("TXkgdGVzdCBzdHJpbmc/".matches(regex)){
    System.out.println("it's a Base64");
}

... 공간이 있으면 Base64가 될 수없는 간단한 유효성 검사를 수행 할 수도 있습니다.

String myString = "Hello World";
 if(myString.contains(" ")){
   System.out.println("Not B64");
 }else{
    System.out.println("Could be B64 encoded, since it has no spaces");
 }

좋아, 그럼 해결책을 줄 수 있니?
Marco

0

디코딩 할 때 ASCII 문자로 된 문자열을 얻는다면 문자열이 인코딩되지 않은 것입니다

(RoR) 루비 솔루션 :

def encoded?(str)
  Base64.decode64(str.downcase).scan(/[^[:ascii:]]/).count.zero?
end

def decoded?(str)
  Base64.decode64(str.downcase).scan(/[^[:ascii:]]/).count > 0
end

0

나는 이것을 사용하려고 노력한다.

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

하지만 적어도 문자의 끝이 =인지 확인하는 조건을 추가했습니다.

string.lastIndexOf("=") >= 0

확인 =: 어떤 사양 Base64을 사용하고 있습니까? end of the character의미 는 무엇 이며, 음수가 아닌 것은 어떻게 lastIndexOf()확인합니까?
greybeard
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.