Подтвердить что ты не робот

Проверьте строку, чтобы увидеть, являются ли все символы шестнадцатеричными значениями

Каков наиболее эффективный способ в С# 2.0 проверить каждый символ в строке и вернуть значение true, если все допустимые шестнадцатеричные символы и false в противном случае?

Пример

void Test()
{
    OnlyHexInString("123ABC"); // Returns true
    OnlyHexInString("123def"); // Returns true
    OnlyHexInString("123g"); // Returns false
}

bool OnlyHexInString(string text)
{
    // Most efficient algorithm to check each digit in C# 2.0 goes here
}
4b9b3361

Ответ 1

public bool OnlyHexInString(string test)
{
    // For C-style hex notation (0xFF) you can use @"\A\b(0[xX])?[0-9a-fA-F]+\b\Z"
    return System.Text.RegularExpressions.Regex.IsMatch(test, @"\A\b[0-9a-fA-F]+\b\Z");
}

Ответ 2

Что-то вроде этого:

(Я не знаю С#, поэтому я не уверен, как прокручивать строки строки.)

loop through the chars {
    bool is_hex_char = (current_char >= '0' && current_char <= '9') ||
                       (current_char >= 'a' && current_char <= 'f') ||
                       (current_char >= 'A' && current_char <= 'F');

    if (!is_hex_char) {
        return false;
    }
}

return true;

Код для логики выше

private bool IsHex(IEnumerable<char> chars)
{
    bool isHex; 
    foreach(var c in chars)
    {
        isHex = ((c >= '0' && c <= '9') || 
                 (c >= 'a' && c <= 'f') || 
                 (c >= 'A' && c <= 'F'));

        if(!isHex)
            return false;
    }
    return true;
}

Ответ 3

Вы можете сделать TryParse в строке, чтобы проверить, является ли строка в ее entirity шестнадцатеричным числом.

Если это особенно длинная строка, вы можете взять ее в куски и пройти через нее.

// string hex = "bacg123"; Doesn't parse
// string hex = "bac123"; Parses
string hex = "bacg123";
long output;
long.TryParse(hex, System.Globalization.NumberStyles.HexNumber, null, out output);

Ответ 5

Вот версия LINQ yjerem выше:

private static bool IsValidHexString(IEnumerable<char> hexString)
{
    return hexString.Select(currentCharacter =>
                (currentCharacter >= '0' && currentCharacter <= '9') ||
                (currentCharacter >= 'a' && currentCharacter <= 'f') ||
                (currentCharacter >= 'A' && currentCharacter <= 'F')).All(isHexCharacter => isHexCharacter);
}

Ответ 6

Публикация VB.NET-версии ответ Джереми, потому что я пришел сюда, ища такую ​​версию. Должно быть легко преобразовать его в С#.

''' <summary>
'''   Checks if a string contains ONLY hexadecimal digits.
''' </summary>
''' <param name="str">String to check.</param>
''' <returns>
'''   True if string is a hexadecimal number, False if otherwise.
''' </returns>
Public Function IsHex(ByVal str As String) As Boolean
    If String.IsNullOrWhiteSpace(str) Then _
        Return False

    Dim i As Int32, c As Char

    If str.IndexOf("0x") = 0 Then _
        str = str.Substring(2)

    While (i < str.Length)
        c = str.Chars(i)

        If Not (((c >= "0"c) AndAlso (c <= "9"c)) OrElse
                ((c >= "a"c) AndAlso (c <= "f"c)) OrElse
                ((c >= "A"c) AndAlso (c <= "F"c))) _
        Then
            Return False
        Else
            i += 1
        End If
    End While

    Return True
End Function

Ответ 7

Регулярное выражение не очень эффективно в лучшие времена. Наиболее эффективным будет использование простого цикла for для поиска по символам строки и разбиение первого найденного недопустимого.

Однако это можно сделать очень лаконично с LINQ:

bool isHex = 
    myString.ToCharArray().Any(c => !"0123456789abcdefABCDEF".Contains(c));

Я не могу ручаться за эффективность, поскольку LINQ является LINQ, но Any() должен иметь довольно хорошо оптимизированную схему компиляции.

Ответ 8

Как насчет:

bool isHex = text.All("0123456789abcdefABCDEF".Contains);

В основном это говорит: проверьте, существуют ли все символы в строке text в строке допустимых шестнадцатеричных значений.

Какое из них является самым простым и доступным для чтения решением.

(не забудьте добавить using System.Linq;)

EDIT:
Просто заметили, что Enumerable.All() доступен только с .NET 3.5.

Ответ 9

С точки зрения производительности самый быстрый, скорее всего, просто перечислит символы и проведет простую проверку сравнения.

bool OnlyHexInString(string text) {
  for (var i = 0; i < text.Length; i++) {
    var current = text[i];
    if (!(Char.IsDigit(current) || (current >= 'a' && current <= 'f'))) {
      return false;
    }
  }
  return true;
}

Чтобы действительно узнать, какой метод является самым быстрым, хотя вам нужно выполнить профилирование.

Ответ 10

    //Another workaround, although RegularExpressions is the best solution
     boolean OnlyHexInString(String text)
    {
      for(int i = 0; i < text.size(); i++)
        if( !Uri.IsHexDigit(text.charAt(i)) )
          return false;
      return true;
    }

Ответ 11

В терминах времени программиста, вероятно, лучше всего назвать функцию синтаксического анализа на основе строковой цепочки (например, Java Integer.parseInt(str, base)) и посмотреть, получаете ли вы исключение. Если вы хотите написать его самостоятельно и потенциально иметь больше времени/пространства-эффективности...

Наиболее эффективным я предполагаю, что это будет таблица поиска для каждого символа. У вас будет массив 2 ^ 8 (или 2 ^ 16 для Unicode) -entry из булевых, каждый из которых будет истинным, если он является допустимым шестнадцатеричным символом, или false, если нет. Код будет выглядеть примерно так (в Java, извините; -):

boolean lut[256]={false,false,true,........}

boolean OnlyHexInString(String text)
{
  for(int i = 0; i < text.size(); i++)
    if(!lut[text.charAt(i)])
      return false;
  return true;
}

Ответ 12

Это можно сделать с помощью регулярных выражений, которые являются эффективным способом проверки соответствия строки конкретному шаблону.

Возможное регулярное выражение для шестнадцатеричной цифры будет [A-Ha-h0-9], некоторые реализации даже имеют конкретный код для шестнадцатеричных цифр, например. [[: Xdigit:]].

Ответ 13

Вы можете расширить строку и char, используя следующую команду:

    public static bool IsHex(this string value)
    {   return value.All(c => c.IsHex()); }

    public static bool IsHex(this char c)
    {
        c = Char.ToLower(c);
        if (Char.IsDigit(c) || (c >= 'a' && c <= 'f'))
            return true;
        else
            return false;
    }

Ответ 14

Легкое решение без регулярных выражений:

VB.NET:

Public Function IsHexString(value As String) As Boolean
    Dim hx As String = "0123456789ABCDEF"
    For Each c As Char In value.ToUpper
        If Not hx.Contains(c) Then Return False
    Next
    Return True
End Function

Или в С#

public bool IsHexString(string value)
{
    string hx = "0123456789ABCDEF";
    foreach (char c in value.ToUpper()) {
        if (!hx.Contains(c))
        return false;
    }
    return true;
}

Ответ 15

Я использую этот метод:

public static bool IsHex(this char c)
{
  return   (c >= '0' && c <= '9') ||
           (c >= 'a' && c <= 'f') ||
           (c >= 'A' && c <= 'F');
}

Ответ 16

И это как метод расширения С#...

public static class StringExtensions
{
    public static bool IsHexString(this string str)
    {
        foreach (var c in str)
        {
            var isHex = ((c >= '0' && c <= '9') ||
                          (c >= 'a' && c <= 'f') ||
                          (c >= 'A' && c <= 'F'));

            if (!isHex)
            {
                return false;
            }
        }

        return true;
    }

    //bonus, verify whether a string can be parsed as byte[]
    public static bool IsParseableToByteArray(this string str)
    {
        return IsHexString(str) && str.Length % 2 == 0;
    }
}

Используйте его так...

if("08c9b54d1099e73d121c4200168f252e6e75d215969d253e074a9457d0401cc6".IsHexString())
{
    //returns true...
}

Ответ 17

Я сделал это решение для решения этой проблемы. Убедитесь, что перед выполнением строки запроса не имеет значения.

for (int i = 0; i < Request.Length; i += 2)
  if (!byte.TryParse(string.Join("", Request.Skip(i).Take(2)), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out _)) return false;

Ответ 18

public static bool HexInCardUID(string test)
        {
            if (test.Trim().Length != 14)
                return false;
            for (int i = 0; i < test.Length; i++)
                if (!Uri.IsHexDigit(Convert.ToChar(test.Substring(i, 1))))
                    return false;
            return true;
        }**strong text**

Ответ 19

Теперь только

if (IsHex(text)) {
    return true;
} else {
    return false;
}