Активный отдых мозгами

26 июл. 2012 г. | | |

Я обожаю всякие квесты, особенно те, что связаны с профессией. Поэтому, с удовольствием прошла тест и поучаствовала в квесте ко дню сисадмина на admin2012.ru от компании Ideco.
Особенно понравились задания с bash-скриптами, оторваться было просто невозможно!
В квесте понравились задания с подсчетом анаграмм в "Война и мир" и с восстановлением номера кредитной карты. Последнее задание дало почувствовать себя кулхацкером: восстановление кода платежной карты, как никак! Первая шальная мысль, после прочтения задания, была "Ну не SHA256 же взламывать-то предлагают!", а вторая "Надо бы погуглить, как рассчитывается контрольный номер карты". И, да, сработало:по алгоритму проверяем валидность карты, при положительном результате вычисляем хэш и сравниваем с хэшем из задания. Реализация навскидку:
class Program
    {
        const string sha256hash = "9872ecc9bc3aec3889eb54059e36aa8b760a3767ea9e1a9804e82671dc957e80";
        const int sum_of_know_card_numbers = 21;

        static void Main(string[] args)
        {
            int[] nums = new int[] { 0, 0, 0, 0, 0, 0, 0, 0 };
            int[] mask = new int[] { 2, 1, 2, 1, 2, 1, 2, 1 };
            string cardnumber;
            while (nums[0] < 10)
            {
                var res = transform(nums, mask);
                var sum = res.Sum();
                if ((sum + sum_of_know_card_numbers) % 10 == 0)
                    if (check_hash(nums, out cardnumber))
                    {
                        Console.WriteLine(cardnumber); break;
                    }
                nums = increment(nums);
            }
            Console.ReadKey();
        }

        static int[] transform(int[] arr1, int[] arr2)
        {
            int[] result = new int[8];
            for (int i = 0; i < arr1.Length; i++)
            {
                result[i] = arr1[i] * arr2[i];
                if (result[i] >= 10)
                    result[i] = result[i] - 9;
            }
            return result;
        }

        static int[] increment(int[] arr)
        {
            int[] result = new int[] { 0, 0, 0, 0, 0, 0, 0, 1 };
            for (int i = arr.Length - 1; i >= 0; i--)
            {
                result[i] += arr[i];
                if (result[i] == 10)
                {
                    if (i != 0)
                    {
                        result[i] = 0;
                        result[i - 1] += 1;
                    }
                }
            }
            return result;
        }

        static bool check_hash(int[] arr, out string cardnumber)
        {
            cardnumber = null;
            var cardnum = "5213" + arr2str(arr) + "3452";          
            using (var hashalg = new SHA256CryptoServiceProvider())
            {
                var hashbytes = hashalg
                                .ComputeHash(
                                Encoding.Default.GetBytes(cardnum)
                                );
                var hash = BitConverter.ToString(hashbytes)
                                       .ToLower().Replace("-", "");
                if (sha256hash == hash)
                {
                    cardnumber = cardnum;
                    return true;
                }
            }
            return false;
        }

        static string arr2str(int[] arr)
        {
            var str = "";
            foreach (var n in arr)
            {
                str += n.ToString();
            }
            return str;
        }
    }

0 коммент.:

Отправить комментарий