2017-01-20 5 views
2

Что это за функция, я имею в виду для части, где есть 0x30? Значение Hex указывает на таблицу ASCII? Это, вероятно, базовый материал, и я не знаю в настоящее время.Не знаю, как читать этот метод

getCompleteCode("11111"); 

private string getCompleteCode(string code) 
     { 
      var b1 = 10; 
      var b2 = 20; 
      var sum = 0; 
      for (var i = code.Length - 1; i >= 0; i--) 
      { 
       var z = code[i] - 0x30; 
       sum = sum + (z + b1) * b2; 

      } 

      Console.WriteLine(sum); 

      return code; 
} 
+2

0x30 это символ «0». Таким образом, вычитание 0x30 из текущего символа ('code [i]') должно давать численное значение этого символа. Имеет очевидный недостаток без ограничений, чтобы убедиться, что символ * на самом деле * числовой. Математика с b1 и b2 представляется специфичной для контекста. Трудно догадаться. –

+0

Это довольно ужасный код, особенно если он используется в производственной среде. Это чересчур многословно, имеет магические числа повсюду и пытается быть умным, проскальзывая в 0x30 вместо того, чтобы просто использовать «0». –

+0

C# 'string' и' char' не используют ASCII. 0x30 - UTF-16 для '0'. В коде «0» намного легче читать. UTF-16 является одним из нескольких кодировок для набора символов Unicode. (UTF-8 очень часто используется для файлов и потоков, таких как эта веб-страница.) [BTW-Java, JavaScript, HTML, XML, ... все тоже используют Unicode.] –

ответ

1

Как пояснили другие, var z = code[i] - 0x30 - это стандартный код, чтобы получить значение знака цифры. Как отметил Глорин Оакенфут, этот код не выполняет никаких ограничений. Поэтому он отлично работает для «0» - 0x30 (фактически, это «0» - «0», кстати), а для «9» - 0x30. Но это также произведет странность как «A» - 0x30 = 32.

Комментарий Глорина также прав - остальные номера кажутся очень специфичными для контекста. Вероятно, это хеш-функция - она ​​вычисляет в основном уникальное число для данной строки. Я проведу вас через петлю, но то, что она делает, не имеет никакого реального смысла. Вместо ввода «11111» давайте посмотрим на «12345»:

1-й тайм-цикл: i = 4, код [i] = '5', z = 5, sum = 0 + 15 * 20 = 300

второй раз через петлю: я = 3, код [I] = '4', г = 4, сумма = 300 + 14 * 20 = 580

3-й раз через петлю: я = 2, код [я ] = '3', z = 3, sum = 580 + 13 * 20 = 840

4-я временная петля: i = 1, код [i] = '2', z = 2, sum = 840 + 12 * 20 = 1080

Пятый раз через цикл: i = 0, код [i] = '1', z = 1, sum = 1080 + 11 * 20 = 1300

Как я уже говорил, это, скорее всего, используется для хеширования. Каждая строка цифр, которые вы вводите, скорее всего, будет иметь уникальный целочисленный код. Хеширование струн может повысить эффективность. Если ничего другого, это дает вам довольно надежный тест для сравнения. См. https://en.wikipedia.org/wiki/Hash_function

Конечно, большинство строковых хэш-функций не выполняют преобразование из цифры в int. И если функция требует, чтобы входные данные были только цифрами, что, как представляется, подразумевается преобразованием в int, простейший хеш для этой строки состоит в том, чтобы просто проанализировать ее на целое число.

Другое, что мне напоминает, это попытка разобрать целую строку на цифру. Это было бы очень похожи, но обратите внимание на различия ниже:

var sum = 0 
for (var i = 0; i < code.Length; i++) 
{ 
    var z = code[i] - '0' // this is the same as - 0x30, but more clear to read 
    sum = sum * 10 + z 
} 

УЧИТЫВАЯ имя функции, хотя, кажется, гораздо более вероятно, что она предназначена в качестве хэш-функции.

+0

Как представляется, это не хэш-алгоритм - для хорошего хэша вы умножаетесь на простое число, например 19, а не на 20. Это не алгоритм Луна для проверки номера кредитной карты, это не алгоритм crc ... –

+0

Никто не знает, что это (хэш, некоторая кодировка, вид контрольного номера, просто домашнее задание); для меня это хороший пример того, как один * не должен реализовывать логику (отметьте по крайней мере пять ошибок в коде, и вы станете викториной);) –

0

0x30 y шестнадцатеричный код ASCII для номера 0, поэтому z фактически даст вам цифру в виде номера.

1

0x30 - это значение ascii '0' ... оно обычно используется для вычитания из символа, например. '8' - 0x30 = 8 после литья в целое число (неявно или явно здесь).

-1

Удаляет десятичные знаки. Это = любое число округленное.

3

Замечательный пример того, как один не реализовать логику:

// why not static? 
    private string getCompleteCode(string code) 
    { 
     // what does "b1" as well as "b2" stand for? 
     var b1 = 10; 
     var b2 = 20; 
     var sum = 0; 
     // the reason for the loop being in reversed order? 
     for (var i = code.Length - 1; i >= 0; i--) 
     { 
      // the question put - what does 0x30 stand for - it's ascii code of '0' char 
      // so, why magic code 0x30 instead of evident '0'? 
      var z = code[i] - 0x30; 
      sum = sum + (z + b1) * b2; 
     } 

     // what if I want to compute it in, say, WinForms?? 
     // Never mix business logic (computing some code) and UI (output) 
     Console.WriteLine(sum); 

     // we've done a lot of stuff just to return the initial input?? 
     return code; 
    } 

Мое предложение для реализации (при условии, что code гарантированно будет правильный вход):

//TODO: think on a better name for the method 
    private static int getCompleteCode(string code) { 
     return code.Sum(c => (c - '0' + 10) * 20); 
    } 

    ... 

    Console.WriteLine(getCompleteCode("11111")); 
+0

Согласитесь, я бы добавил 'int.TryParse' в' code', и если он возвращает false, возможно, генерирует исключение, в противном случае продолжить вызов 'code.Sum'. – gmiley

+0

@gmiley: был метод 'public' one, * validation * (через' int.TryParse', как вы предложили) будет * обязательным * ('public' метод должен работать с * любым * вводом). Тем не менее, метод является 'private', поэтому мы можем предположить, что проверка выполняется где-то, и мы гарантируем, что вход всегда правильный. –

+0

Да, я понял только минуту назад, что мы имеем дело с «частным», но было слишком поздно пересматривать мой комментарий, поэтому я не собирался беспокоиться. Это верно, хотя можно утверждать, что действительный вход «private» может быть принят. – gmiley

Смежные вопросы