유효한 Base64 인코딩 암호화를 확인하는 방법
C #에서 인코딩이 Base 64로 인코딩 확인하는 방법이 있습니까? 변환을 시도하고 오류가 있는지 확인하는 것 외에는 무엇입니까? 다음과 같은 코드 코드가 있습니다.
// Convert base64-encoded hash value into a byte array.
byte[] HashBytes = Convert.FromBase64String(Value);
"Base-64 문자열에서 유효하지 않은 문자"예외를 사용하고 싶습니다. 64 개의 권장 사항이 아닐 경우 처리하는 대신 거짓을 확인하고 반환하고 싶습니다. Convert.FromBase64String 함수를 사용하기 전에 확인할 수있는 방법이 있습니까?
감사합니다!
업데이트 :
모든 답변에 감사드립니다. 다음은 지금까지 사용할 수있는 확장 방법입니다. 예외가 예외없이 Convert.FromBase64String을 전달하는지 확인하는 것입니다. .NET은 기본 64로 변환 할 때 모든 후행 및 끝 공백을 무시하는 것처럼 보 곧 "1234"가 유효하고 "1234"도합니다.
public static bool IsBase64String(this string s)
{
s = s.Trim();
return (s.Length % 4 == 0) && Regex.IsMatch(s, @"^[a-zA-Z0-9\+/]*={0,3}$", RegexOptions.None);
}
테스트 대 캐치 및 예외의 성능에 대해 궁금한 사람들을 위해 대부분의 경우가베이스 64의 경우 특정 길이에 도달 할 때까지 예외가되는 것보다 빠릅니다. 길이가 작을수록 빨라 빨라
내 매우 비과학적인 테스트에서 : 문자 길이 100,000-110000에 대해 10000 번 반복하는 경우 먼저 테스트하는 것이 2.7 배 더 빨랐습니다.
총 16,000 개의 테스트에서 1-16 자 길이의 문자 길이에 대해 1000 번 반복하면 10.9 배 더 빨라집니다.
예외 방법으로 테스트하는 것이 더 나아지는 지점이 확신합니다. 나는 그것이 어떤 시점인지 모른다.
Base64는 문자로만 구성 'A'..'Z', 'a'..'z', '0'..'9', '+', '/'
되고 길이를 4의 배수로 만들기 위해 최대 2 개의 '='로 채워지는 경우가 많기 때문에 인식하기가 매우 많지만 비교하는 대신에 'd 예외가 발생하면 무시하는 것이 좋습니다 .
예외를하고 싶지 않다고합니다. 예외를 잡는 것이 더 있지만 수 있기 때문에 계속 해서이 답변을 게시하겠습니다.
public static bool IsBase64(this string base64String) {
// Credit: oybek https://stackoverflow.com/users/794764/oybek
if (string.IsNullOrEmpty(base64String) || base64String.Length % 4 != 0
|| base64String.Contains(" ") || base64String.Contains("\t") || base64String.Contains("\r") || base64String.Contains("\n"))
return false;
try{
Convert.FromBase64String(base64String);
return true;
}
catch(Exception exception){
// Handle the exception
}
return false;
}
업데이트 : 신뢰성을 더욱 향상시키기 위해 oybek 덕분에 상태를 업데이트했습니다 .
C # 7.2에서 Convert.TryFromBase64String 사용
public static bool IsBase64String(string base64)
{
Span<byte> buffer = new Span<byte>(new byte[base64.Length]);
return Convert.TryFromBase64String(base64, buffer , out int bytesParsed);
}
정규식은 다음 과소 생각합니다.
Regex.IsMatch(s, @"^[a-zA-Z0-9\+/]*={0,2}$")
3 개가 아닌 하나 또는 2 개의 후행 '='기호 만 일치합니다.
s
반드시 있어야합니다. 네임 스페이스의 일부 Regex
입니다 System.Text.RegularExpressions
.
왜 예외를 잡아서 False를 반환하지 않습니까?
이것은 일반적인 경우에 추가 오버 헤드를 방지합니다.
완전성을 위해 일부 구현을 제공하고 싶습니다. 일반적으로 Regex는 비용이 많이 많이 접근 방식입니다. 큰 파일을 많은 경우 (큰 파일을 가질 때). 다음 접근 방식은 가장 빠른 검색 방법을 먼저 시도합니다.
public static class HelperExtensions {
// Characters that are used in base64 strings.
private static Char[] Base64Chars = new[] { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/' };
/// <summary>
/// Extension method to test whether the value is a base64 string
/// </summary>
/// <param name="value">Value to test</param>
/// <returns>Boolean value, true if the string is base64, otherwise false</returns>
public static Boolean IsBase64String(this String value) {
// The quickest test. If the value is null or is equal to 0 it is not base64
// Base64 string's length is always divisible by four, i.e. 8, 16, 20 etc.
// If it is not you can return false. Quite effective
// Further, if it meets the above criterias, then test for spaces.
// If it contains spaces, it is not base64
if (value == null || value.Length == 0 || value.Length % 4 != 0
|| value.Contains(' ') || value.Contains('\t') || value.Contains('\r') || value.Contains('\n'))
return false;
// 98% of all non base64 values are invalidated by this time.
var index = value.Length - 1;
// if there is padding step back
if (value[index] == '=')
index--;
// if there are two padding chars step back a second time
if (value[index] == '=')
index--;
// Now traverse over characters
// You should note that I'm not creating any copy of the existing strings,
// assuming that they may be quite large
for (var i = 0; i <= index; i++)
// If any of the character is not from the allowed list
if (!Base64Chars.Contains(value[i]))
// return false
return false;
// If we got here, then the value is a valid base64 string
return true;
}
}
편집하다
Sam이 제안한대로 소스 코드를 약간의 수도 있습니다. 그는 테스트의 마지막 단계에 더 나은 성능을 제공합니다. 루틴
private static Boolean IsInvalid(char value) {
var intValue = (Int32)value;
// 1 - 9
if (intValue >= 48 && intValue <= 57)
return false;
// A - Z
if (intValue >= 65 && intValue <= 90)
return false;
// a - z
if (intValue >= 97 && intValue <= 122)
return false;
// + or /
return intValue != 43 && intValue != 47;
}
if (!Base64Chars.Contains(value[i]))
줄을 다음으로 대체 할 수 있습니다.if (IsInvalid(value[i]))
Sam의 포함 기능이 포함 된 전체 소스 코드 는 다음과 가능합니다 (명확성을 위해 주석 제거).
public static class HelperExtensions {
public static Boolean IsBase64String(this String value) {
if (value == null || value.Length == 0 || value.Length % 4 != 0
|| value.Contains(' ') || value.Contains('\t') || value.Contains('\r') || value.Contains('\n'))
return false;
var index = value.Length - 1;
if (value[index] == '=')
index--;
if (value[index] == '=')
index--;
for (var i = 0; i <= index; i++)
if (IsInvalid(value[i]))
return false;
return true;
}
// Make it private as there is the name makes no sense for an outside caller
private static Boolean IsInvalid(char value) {
var intValue = (Int32)value;
if (intValue >= 48 && intValue <= 57)
return false;
if (intValue >= 65 && intValue <= 90)
return false;
if (intValue >= 97 && intValue <= 122)
return false;
return intValue != 43 && intValue != 47;
}
}
대답은 설치에 따라 달라집니다. 여러 포스터에서 제안한 구문에 따르면 "유효한 base64"일 수있는 예외없이 정크로 "올바르게 예외없이"디코딩 할 수있는 곳이 있습니다. 예 : 8char 유효한 Portland
은 유효한 Base64입니다. 이것이 유효한 Base64라는 점은 무엇입니까? 어느 시점에서 사용 해야하는지 Base64로 사용하는지 여부를 알고 싶을 것입니다.
제 경우에는 다음과 같은 일반 텍스트 일 수있는 Oracle 연결이 있습니다.
Data source=mydb/DBNAME;User Id=Roland;Password=.....`
또는 base64에서
VXNlciBJZD1sa.....................................==
세미콜론이 있는지 확인해야합니다. 왜냐하면 base64가 아니라는 것을 증명하기 때문입니다. 물론 위의 방법보다 빠 사용.
Knibb 높은 축구 규칙!
이것은 거치지 않으면 철저한 테스트를 거치지 않습니다.
값 비싼 예외, 정규식을 피하고 유효성 검사를 위해 ascii 범위를 사용하는 대신 문자 집합을 통해 반복되는 것을 방지합니다.
public static bool IsBase64String(string s)
{
s = s.Trim();
int mod4 = s.Length % 4;
if(mod4!=0){
return false;
}
int i=0;
bool checkPadding = false;
int paddingCount = 1;//only applies when the first is encountered.
for(i=0;i<s.Length;i++){
char c = s[i];
if (checkPadding)
{
if (c != '=')
{
return false;
}
paddingCount++;
if (paddingCount > 3)
{
return false;
}
continue;
}
if(c>='A' && c<='z' || c>='0' && c<='9'){
continue;
}
switch(c){
case '+':
case '/':
continue;
case '=':
checkPadding = true;
continue;
}
return false;
}
//if here
//, length was correct
//, there were no invalid characters
//, padding was correct
return true;
}
public static bool IsBase64String1(string value)
{
if (string.IsNullOrEmpty(value))
{
return false;
}
try
{
Convert.FromBase64String(value);
if (value.EndsWith("="))
{
value = value.Trim();
int mod4 = value.Length % 4;
if (mod4 != 0)
{
return false;
}
return true;
}
else
{
return false;
}
}
catch (FormatException)
{
return false;
}
}
다시 변환 메소드를 호출 할 필요가 정말 이렇게 사용하겠습니다.
public static bool IsBase64(this string base64String,out byte[] bytes)
{
bytes = null;
// Credit: oybek http://stackoverflow.com/users/794764/oybek
if (string.IsNullOrEmpty(base64String) || base64String.Length % 4 != 0
|| base64String.Contains(" ") || base64String.Contains("\t") || base64String.Contains("\r") || base64String.Contains("\n"))
return false;
try
{
bytes=Convert.FromBase64String(base64String);
return true;
}
catch (Exception)
{
// Handle the exception
}
return false;
}
Imho는 정말 불가능합니다. "test" 게시 같은 모든 솔루션은 실패합니다 . 4로 나눌 수 있고 null이 아니거나 비어 있지 않고 유효한 base64 문자이면 모든 테스트를 통과합니다. 그것은 많은 것들이 될 수 있습니다 ...
따라서 64로 인코딩 된 인코딩 된 것 외에는 실제적인 것 입니다. 내가 생각하는 것은 다음과 가변적이다.
if (base64DecodedString.StartsWith("<xml>")
{
// This was really a base64 encoded string I was expecting. Yippie!
}
else
{
// This is gibberish.
}
더 많이 사용되는 특정 구조로 시작될 것으로 예상됩니다.
확실한. 그냥 확인 각 문자 내에 있도록 a-z
, A-Z
, 0-9
, /
, 또는 +
로, 그리고 문자열의 끝 ==
. (적어도, 그것은 가장 일반적인 Base64로 구현합니다. 당신은 일부 구현에서 사용하는 문자 다른 사실을 발견 /
또는 +
마지막 두 문자.)
예, Base64 는 제한된 문자 집합을 사용하여 이진 데이터를 ASCII 문자열로 인코딩 하므로 다음 정규식으로 간단히 확인할 수 있습니다.
/ ^ [A-Za-z0-9 \ = \ + \ / \ s \ n] + $ / s
그러면 문자열에 AZ, az, 0-9, '+', '/', '='및 공백 만 포함됩니다.
나는 일을하기 위해 정규식을 만드는 것이 좋습니다. 다음과 같은 것을 확인해야합니다. [a-zA-Z0-9 + / =] 또한 문자열의 길이도 확인해야합니다. 나는 이것에 대해 확신하지 못하지만, 무언가가 다듬어지면 (패딩 "="이외의) 그것이 터질 것이라고 확신합니다.
또는 이 stackoverflow 질문을 확인하십시오.
사용자가 <canvas>
요소 에서 일부 이미지 조작을 수행 한 다음 검색된 결과 이미지 .toDataURL()
를 백엔드 로 보내는 매우 유사한 요구 사항이 있습니다. 이미지를 저장하기 전에 서버 유효성 검사를 수행하고 ValidationAttribute
다른 답변의 일부 코드를 사용하여 구현했습니다 .
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = false)]
public class Bae64PngImageAttribute : ValidationAttribute
{
public override bool IsValid(object value)
{
if (value == null || string.IsNullOrWhiteSpace(value as string))
return true; // not concerned with whether or not this field is required
var base64string = (value as string).Trim();
// we are expecting a URL type string
if (!base64string.StartsWith("data:image/png;base64,"))
return false;
base64string = base64string.Substring("data:image/png;base64,".Length);
// match length and regular expression
if (base64string.Length % 4 != 0 || !Regex.IsMatch(base64string, @"^[a-zA-Z0-9\+/]*={0,3}$", RegexOptions.None))
return false;
// finally, try to convert it to a byte array and catch exceptions
try
{
byte[] converted = Convert.FromBase64String(base64string);
return true;
}
catch(Exception)
{
return false;
}
}
}
보시다시피 .NET을 <canvas>
사용할 때 반환되는 기본값 인 image / png 유형 문자열이 필요합니다 .toDataURL()
.
디코딩, 다시 인코딩 및 결과를 원래 문자열과 비교합니다.
public static Boolean IsBase64(this String str)
{
if ((str.Length % 4) != 0)
{
return false;
}
//decode - encode and compare
try
{
string decoded = System.Text.Encoding.UTF8.GetString(System.Convert.FromBase64String(str));
string encoded = System.Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(decoded));
if (str.Equals(encoded, StringComparison.InvariantCultureIgnoreCase))
{
return true;
}
}
catch { }
return false;
}
정규식 확인 아이디어가 마음에 듭니다. 정규식은 빠르며 때때로 코딩 오버 헤드를 줄일 수 있습니다. 원래 문의에는이 작업을 수행하는 업데이트가 있습니다. 그래도 문자열이 null이 아닐 것이라고 결코 가정 할 수 없습니다. 확장 함수를 확장하여 소스 문자열에서 null 또는 공백 문자 만 확인합니다.
public static bool IsBase64String(this string s)
{
if (string.IsNullOrWhiteSpace(s))
return false;
s = s.Trim();
return (s.Length % 4 == 0) && Regex.IsMatch(s, @"^[a-zA-Z0-9\+/]*={0,3}$", RegexOptions.None);
}
참고 URL : https://stackoverflow.com/questions/6309379/how-to-check-for-a-valid-base64-encoded-string
'IT' 카테고리의 다른 글
Meteor JavaScript 프레임 워크는 어떻게 작동합니까? (0) | 2020.08.08 |
---|---|
(1) 대. (0) | 2020.08.08 |
Jasmine으로 AngularJS 서비스를 어떻게 테스트합니까? (0) | 2020.08.08 |
macOS Sierra에서 네트워크 링크 조절기가 작동하지 않음 (0) | 2020.08.08 |
끝에 세미콜론이 필요합니까? (0) | 2020.08.08 |