DO#
Prawdopodobnie szalony, rondo i zawiły sposób na uzyskanie (dokładnego) wyniku - tylko ze zmiennymi nazwami i bez żadnej dosłownej „mamy” w żadnym kodzie.
Czytanie zasady „jeśli weźmiesz blok kodu z posta, weźmiesz wszystko” bardzo dosłownie prawdopodobnie nie pomogło - ale sprawiło, że było fajniej.
using System;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
public class Program
{
void Main()
{
// Step 1
var n = 3;
var helloAndGoodbye = "12345678900"
.Select((c, i) => new { letter = c, group = i / n })
.GroupBy(l => l.group, l => l.letter)
.Select(g => string.Join("", g))
.ToList();
// Step 2
string place = "world";
string greet = String.Format("Hello {0}!", place);
// Step 3
byte[] b1 = System.Text.Encoding.UTF8.GetBytes (greet);
byte[] b2 = System.Text.Encoding.ASCII.GetBytes (greet);
// Step 4
string encryptionKey = "test";
var md5 = MD5.Create();
var keyBytes = Encoding.UTF8.GetBytes(encryptionKey);
byte[] encryptionKeyBytes = md5.ComputeHash(keyBytes);
// Step 5
string strName = md5.GetType().Name;
if(strName == "Person")
{
//My Code
}
// Step 6
string HashAlgorithm = new string(strName.Take(n).ToArray());
// Step 7
int previousYear = DateTime.Now.AddYears(-1).Year;
// Step 8
string myString = previousYear.ToString();
// Step 9
string totallyRandomString = new string(myString.Take(n).ToArray());
// Step 10
int myInt = System.Convert.ToInt32(totallyRandomString);
// Step 11
int x = myInt << 1 + 1;
// Step 12
PasswordDeriveBytes DerivedPassword =
new PasswordDeriveBytes(place, b1, HashAlgorithm, x);
byte[] KeyBytes = DerivedPassword.GetBytes(32);
// Step 13
string base64 = Convert.ToBase64String(KeyBytes);
byte[] bytes = Convert.FromBase64String(base64);
// Step 14
var split = base64.Split('/');
var last = split[split.Length -1];
var prev = split[split.Length -2];
// Step 15
string truncatedToNLength = new string(last.Take(n).ToArray());
// Step 16
Regex rgx = new Regex("[^a-zA-Z0-9 -]");
greet = rgx.Replace(greet, "");
// Step 17
var newString = greet.Replace(place.ToString(), truncatedToNLength);
// Step 18
var searchStr = newString.ToLower();
searchStr = searchStr.Trim();
// Step 19
Console.WriteLine(searchStr);
}
}
.NET Fiddle
http://dotnetfiddle.net/PbjhPn
http://dotnetfiddle.net/bg20wb (z usuniętymi redundantnymi liniami w blokach kodu)
Krótkie wyjaśnienie
Zasadniczo otrzymujemy „Hello world!” z prostego formatu ciągu. Teraz potrzebujemy „mamy”, aby go zastąpić. W tym celu wykorzystujemy zakodowany w Base64 wynik uruchomienia 804 iteracji PBKDF1 przy użyciu MD5 z „world” jako hasłem i „Hello world!” w postaci soli Daje to ciąg „ciSf5cCls1l / MoM ...”. Wydobywamy „MoM” i używamy go jako zamiennika „świata”. Następnie sprzątamy sznurek.
Jak dojść do 804? Poprzedni rok przycięty do trzech znaków (= „201”), a następnie pomnożony przez 4.
Długie wyjaśnienie i atrybucje
1: Zaczynamy od odrobiny przesady wynikającej z reguł. Liczba całkowita 3 jest bardzo ważną stałą w tym programie. Tutaj przypisujemy tę liczbę całkowitą do n
. Musimy uwzględnić cały blok ze źródła. Może być nadmiarowy, ale dobrze się skompiluje, o ile zmienimy nazwę split
zmiennej, której będziemy potrzebować później. Źródło
Zamienione nazwy zmiennych:
split > helloAndGoodbye
2: Ustaw ciąg początkowy („Hello world!”). Źródło
To bardzo osobista wiadomość dla naszej mamy. Więc oczywiście potrzebujemy trochę kryptografii, aby poradzić sobie z tymi typami NSA. W tym celu potrzebujemy parametrów, które teraz przygotowujemy.
3: Konwertuj greet
(„Witaj, świecie!”) Na tablicę bajtów do solenia. Źródło
myString > greet
4: Chociaż korzystamy z kryptografii, tak naprawdę nie musimy tworzyć instancji klasy MD5. Potrzebujemy jednak ciągu „MD5” przypisanego do jednego z naszych parametrów, aby można go było użyć w dalszej części - i nie jest to łatwe do znalezienia w użytecznym kodzie. Więc weźmiemy kolejny ... „skrót”… Raz jeszcze cały blok kodu zawarty zgodnie z regułami, chociaż potrzebujemy tylko drugiej linii. Źródło
5: Teraz potrzebujemy nazwy typu md5
zmiennej ( MD5CryptoServiceProvider
). To if
kolejna redundancja. Źródło
entity > md5
6: Zdobądź pierwsze 3 (ooh, nasze stałe!) Znaki o nazwie typu. Źródło
s > strName
truncatedToNLength > HashAlgorithm
7: Trolling kodu: używanie DateTime.Now
oznaczałoby, że działałoby to tylko do 2019 roku. Aby uczynić to nieco bardziej przyszłym, używamy poprzedniego roku. Wtedy będzie działać do 2020 r .;-) Źródło
8: Konwertuj nasz previousYear
na ciąg. Źródło
myInt > previousYear
9: Hej, ponowne użycie kodu! ;-) Zdobądź pierwsze 3 (nasze stałe!) Postacie naszego roku. Źródło
s > myString
truncatedToNLength > totallyRandomString
10: Aaaaaaa i ... przekształć wynik z powrotem na liczbę całkowitą. Źródło
myString > totallyRandomString
11: Eric Lippert poprawia każdą odpowiedź. Pomnóż przez 4 na rondzie. Źródło
y > myInt
12: Wyślij place
(hasło) i greet
(sól) przez PBKDF1, używając MD5 z x
(obecnie 201*4 = 804
) iteracjami. Źródło
Password > place
SaltValueBytes > b1
PasswordIterations > x
13: Jon Skeet poprawia również każdą odpowiedź. Konwertuj nasze pochodne hasło na bazę 64. Wyrzucamy bytes
tablicę. Źródło
bytes (first occurrence) > KeyBytes
14: Cóż za szalony losowy przypadek! Teraz mamy base64
„MoM”. Dogodnie, tuż przed „MoM” jest singiel „/”. Podziel łańcuch z tym znakiem jako separator: Źródło
filePath > base64
15: Hej, nasz ulubiony kawałek taśmy do ponownego użycia kodu! Zdobądź pierwsze 3 (stałe!) Litery last
. Źródło
s > last
16: Usuń „!”. Źródło
str > greet
17: MoM to nasz świat - więc spraw, aby sznur odzwierciedlał to (zamień „world” na „MoM”). Źródło
someTestString > greet
someID > place
sessionID > truncatedToNLength
18: Na koniec przekonwertuj na małe litery. Przycinaj dla dokładności (lub być może dlatego, że jest to część bloku taśmy izolacyjnej). Źródło
wordToSearchReplacemntsFor > newString
19: Dane wyjściowe do konsoli. Źródło
_surface > searchStr
Trochę „materiału bonusowego” / komentarza
Najpierw próbowałem każdej kombinacji wbudowanych skrótów kryptograficznych (każda w połączeniu z HMAC) i danych wejściowych („świat”, „Witaj świecie!”, „Witaj świecie”, „witaj świecie” itp.), Aby sprawdzić, czy coś cudownie dałoby użyteczny wynik, z którego można wyprowadzić „mamę” - zanim przejdzie się łatwą drogą po prostu szukania szeregu iteracji PDKDB1 (lub 2), które byłyby przydatne.
Nie był do końca zadowolony z wykorzystania roku jako danych wejściowych dla iteracji 201 * 4 = 804. Na początku próbowałem znaleźć użyteczny kod HttpStatusCode.Created
(201) do użycia jako dane wejściowe - z „wymówką trollową” w stylu „stworzyliśmy nasz„ Hello world! ” ciąg, więc dobrą praktyką byłoby użycie tutaj kodu statusu „Utworzono”. Niestety, nigdy nie znalazłem zastosowania HttpStatusCode
wyliczenia, które nie wprowadziłoby zależności od większości frameworku ASPAP .NET WebAPI.
Początek kodu (format ciągu „Hello world!”) Nigdy nie był oglądany po jego pierwszym dodaniu. Gdybym miał, tak, mógłbym zdać sobie sprawę, że przypisanie place
było w rzeczywistości w innym bloku w źródle - więc mógłbym po prostu przypisać moją pochodną „mamę” place
raczej niż używać „świata”, a później go zastąpić. Ach tak.