.Net 4.5 ve C# 5 ile duyurulan CallerMemberName attribute’unun Loglama ve OnPropertyChanged method’unu daha kolay tetiklemek dışında ne işe yarayacağını uzun süre düşündükten sonra, internette gördüğüm bir makale ile aklıma bir fikir geldi. CallerMemberName attribute‘unun kullanım alanlarını inceleyelim;
Loglama
public static void LogException(string message, [CallerMemberName] string callerName = null, [CallerLineNumber] int lineNumber = 0, [CallerFilePath] string filePath = null) { Console.WriteLine(“Hata oluştu : {0}. Method : {1} Satır : {2} Dosya : {3}”, message, callerName, lineNumber, filePath); }
private static void Calculate() { try { /// Veritabanına bağlan, sorgulama yap, hesapla } catch (Exception ex) { LogException(ex.Message); } }</pre>
OnPropertyChanged
OnPropertyChanged method’unu C# 5‘ten önce şöyle tetikleriz;
protected virtual void OnPropertyChanged(string propertyName) { PropertyChangedEventHandler handler = PropertyChanged; if (handler != null) { handler(this, new PropertyChangedEventArgs(propertyName)); } } private string _productName; public string ProductName { get { return _productName; } set { _productName = value; OnPropertyChanged("ProductName"); } }
C# 5 ile birlikte gelen CallerMemberName attribute’unu kullanarak aynı işi şu şekilde yapabiliriz;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) { PropertyChangedEventHandler handler = PropertyChanged; if (handler != null) { handler(this, new PropertyChangedEventArgs(propertyName)); } } private string _productName; public string ProductName { get { return _productName; } set { _productName = value; OnPropertyChanged(); } }
Strategy Pattern
CallerMemberName attribute‘unun yukarıdakilerden farklı kullanımı aşağıdaki gibi olabilir;
public class CustomSerializer { public Func<string> Serialize { get; private set; } public CustomSerializer([CallerMemberName] string memberName = "") { if (memberName.Contains("Xml")) { Serialize = () => { return "xml"; }; } else { Serialize = () => { return "json"; }; } } } public static void WriteXml() { var serializer = new CustomSerializer(); Console.WriteLine(serializer.Serialize()); /// xml } public static void WriteJson() { var serializer = new CustomSerializer(); Console.WriteLine(serializer.Serialize()); /// json } Böylece, *CustomSerializer* class'ında bulunan *Serialize* method'unu çağıran method'un adında *Xml* anahtar kelimesi varsa *Serialize* method'u *xml serialization* yapacak, yoksa *json serialization* yapacak. *Kaynak : Makaleyi tekrar bulamadım :(*
Euler serisinin onuncu yazısında, Project Euler’in 10. sorusunu çözeceğiz;
Orjinal Soru; The sum of the primes below 10 is 2 + 3 + 5 + 7 = 17 Find the sum of all the primes below two million
Türkçesi; 10'dan küçük asal sayıların toplamı 17'dir; 2 + 3 + 5 + 7 = 17 2.000.000'dan küçük tüm asal sayıların toplamını bulun
Önce siz çözmeyi deneyin, çözemezseniz;
private static List<int> Euler10() { int counter = 3; bool isPrime; int j; List<int> primes = new List<int>(); primes.Add(2); while (counter < = 2000000) { j = 0; isPrime = true; while (primes[j] * primes[j] <= counter) { if (counter % primes[j] == 0) { isPrime = false; break; } j++; } if (isPrime) { primes.Add(counter); } counter += 2; } return primes; } public static class Program { public static void Main(string[] args) { var Sonuc = Euler10(); Console.WriteLine("Euler 10 sonuç : " + Sonuc.Sum()) Console.ReadLine(); } }
IEnumerable interface‘inden türetilmiş Student sınıfı aşağıdaki gibidir;
using System; using System.Collections;
public class Student : IEnumerable { public string FullName { get; set; }
private int count;
public int Count { get { return count; } }
public void Add(string fullName)
{
count++;
}
IEnumerator IEnumerable.GetEnumerator()
{
throw new NotSupportedException();
} }</pre>
Student sınıfını kullanan kod parçası aşağıdaki gibidir;
string FullName = "x"; Student student = new Student { FullName = "y" }; Console.WriteLine(FullName); /// x Console.WriteLine(student.FullName); /// y Console.WriteLine(student.Count); /// 0
Student sınıfını kullanan kod parçasını aşağıdaki gibi değiştirelim;
string FullName = "x"; Student student = new Student { ( FullName = "y" ) }; Console.WriteLine(FullName); Console.WriteLine(student.FullName); Console.WriteLine(student.Count); Sizce, yeni kod parçasının çıktısı ne olur?
Euler serisinin dokuzuncu yazısında, Project Euler’in 9. sorusunu çözeceğiz;
Orjinal Soru; A Pythagorean triplet is a set of three natural numbers, a b c For which, a2 + b2 = c2 For example, 32 + 42 = 9 + 16 = 25 = 52 There exists exactly one Pythagorean triplet for which a + b + c = 1000 Find the product a x b x c
Türkçesi; Pisagor teoremindeki üç doğal sayı a b ve c'dir; a2 + b2 = c2 Örneğin, 32 + 42 = 9 + 16 = 25 = 52 a + b + c'nin 1000 değerine sahip olduğu tek bir Pisagor üçlüsü vardır Bu üçlüyü bulup, a x b x c değerini hesaplayın
Önce siz çözmeyi deneyin, çözemezseniz;
private static int Euler9() { int a = 0; int b = 0; int c = 0; int s = 1000; bool found = false; for (a = 1; a < s / 3; a++) { for (b = a; b < s / 2; b++) { c = s - a - b; if (a * a + b * b == c * c) { found = true; break; } } if (found) { break; } } return a * b * c; } public static class Program { public static void Main(string[] args) { var Sonuc = Euler9(); Console.WriteLine("Euler 9 sonuç : " + Sonuc) Console.ReadLine(); } }
Kişiye özel bilgiler barındıran yazılımlar mutlaka kullanıcı bilgilerini güvenlik altına almak için kullanıcının kendi belirlediği Kullanıcı Adı ve Şifresi ile yazılımı kullanmasını sağlar.
Böylece Kullanıcı Adı ve Şifresi‘ni bilmeden bir kullanıcıya özel bilgiler başkaları tarafından görüntülenemez / kopyalanamaz / değiştirilemez.
Başkalarının bilgilerini görmeye / değiştirmeye meraklı (çoğu zaman kötü niyetli) kişiler kurbanlarının Kullanıcı Adı ve Şifresi bilgilerini tahmin ederek sisteme girmeye çalışırlar.
Tahmin metodunun işe yaramadığı durumlarda olası ihtimallerin tamamını sırası ile deneyerek sisteme giriş yapmaya çalışan küçük programcıklar geliştirirler.
Kullanıcının Kullanıcı Adı ve Şifresi ne kadar kolay tahmin edilebilir ise onun adına sisteme girilebilmesi de o kadar kolay olur.
Son yıllarda yazılımlar kullanıcılarının en azından kolay tahmin edilebilir şifre seçememeleri için çeşitli yöntemler geliştirdiler.
Bunlardan bir tanesi Password Strength Check denilen Şifre Güvenlik Testi diye çevirebileceğimiz yöntemdir.
Bu yöntemin temelinde kullanıcının şifre olarak küçük harf , BÜYÜK HARF ve Rakamlardan oluşan uzun bir kelime belirlemesi yatıyor.
Yazılım genelde, kullanıcının şifresini belirlediği ekranda, şifrenin güvenlik seviyesini, mesaj veya görsel ile kullanıcıya geri bildirir.
Eğer biz de yazılımımıza benzer bir kontrol koymak istiyorsak öncelikle şifre güvenlik testi için bir method geliştirmeli, sonra şifreyi ilgili güvenlik test method‘undan geçirmeliyiz.
Güvenlik Testinin kuralları yazılımdan yazılıma göre değişkenlik gösterebilir. Bu makale için aşağıdaki kurallar geçerli olacak;
Kullanıcılara şifrelerinin güvenlik seviyesini 0 ile 100 arası bir rakamla göstermek yerine bu değer üzerinden hesapladığımız daha anlaşılır bir değer ile göstermeliyiz. Kullanıcının göreceği güvenlik seviyeleri listesi;
Bu kurallar ışığında şifre günvelik testi method’umuzu yazmaya başlayalım. Öncelikle projeye PasswordStrengthChecker isminde bir class ekleyelim ve içinde GetLengthScore, GetLowerScore, GetUpperScore, GetDigitScore, GetSymbolScore isimli methodlar tanımlayalım;
public class PasswordStrengthChecker { private int GetLengthScore(string password) { return Math.Min(10, password.Length) * 6; }
private int GetLowerScore(string password)
{
int rawScore = password.Length - Regex.Replace(password, "[a-z]", "").Length;
return Math.Min(2, rawScore) * 5;
}
private int GetUpperScore(string password)
{
int rawScore = password.Length - Regex.Replace(password, "[A-Z]", "").Length;
return Math.Min(2, rawScore) * 5;
}
private int GetDigitScore(string password)
{
int rawScore = password.Length - Regex.Replace(password, "[0-9]", "").Length;
return Math.Min(2, rawScore) * 5;
}
private int GetSymbolScore(string password)
{
int rawScore = Regex.Replace(password, "[a-zA-Z0-9]", "").Length;
return Math.Min(2, rawScore) * 5;
} }</pre>
Aynı class içerisine GeneratePasswordScore isimli method ekleyelim ve ykarıda tanımladığımız method’ları kullanarak şifrenin güvenlik değerini hesaplayalım;
public int GeneratePasswordScore(string password) { if (password == null) { return 0; } int lengthScore = GetLengthScore(password); int lowerScore = GetLowerScore(password); int upperScore = GetUpperScore(password); int digitScore = GetDigitScore(password); int symbolScore = GetSymbolScore(password); return lengthScore + lowerScore + upperScore + digitScore + symbolScore; }
Böylelikle GeneratePasswordScore method’una parametre ile verilen şifrenin güvenlik değerini hesaplayabiliriz. Şimdi bu değeri daha okunabilir / kolay anlaşılabilir hale çevirelim. Öncelikle yeni bir enum eklemeliyiz;
public enum PasswordStrength { Unacceptable, Weak, Normal, Strong, Secure }
PasswordStrengthChecker class’ına son bir method eklememiz gerekiyor;
public PasswordStrength GetPasswordStrength(string password) { int score = GeneratePasswordScore(password); if (score < 50) return PasswordStrength.Unacceptable; else if (score < 60) return PasswordStrength.Weak; else if (score < 80) return PasswordStrength.Normal; else if (score < 90) return PasswordStrength.Strong; else return PasswordStrength.Secure; }
Kullanımına birkaç örnek;
</pre><pre class="brush:csharp">PasswordStrengthChecker checker = new PasswordStrengthChecker(); int score;
score = checker.GeneratePasswordScore(“pwd”); /// 28 score = checker.GeneratePasswordScore(“password”); /// 58 score = checker.GeneratePasswordScore(“P45Sword”); /// 78 score = checker.GeneratePasswordScore(“P45Sword!”); /// 89 score = checker.GeneratePasswordScore(“ASriws34#!”); /// 100
PasswordStrength strength;
strength = checker.GetPasswordStrength(“pwd”); /// Kabul Edilemez strength = checker.GetPasswordStrength(“password”); /// Zayıf strength = checker.GetPasswordStrength(“P45Sword”); /// Normal strength = checker.GetPasswordStrength(“P45Sword!”); /// Güçlü strength = checker.GetPasswordStrength(“ASriws34#!”); /// Güvenli
Kaynak : blackwasp
Senior Software Engineer, @Microsoft
Ada ve Ege'nin babası ;)
Makale Adedi: 484