Math | Engin Polat\'ın Windows 8 , Windows Phone 8 ve C# içerikli programcılık sitesi

Arşiv

Etiketlenen yazılar math

C# ile şifre güvenlik testi

04 February 2013 1 yorum

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;

  • Şifre Güvenlik Seviyesi 0 ile 100 arasında bir puandır
  • Şifre içerdiği her harf 6 puan değerindedir, bu özellikten en fazla 60 puan alınabilir
  • Eğer bir rakam içeriyorsa 5 puan alır, birden fazla rakam içeriyorsa 10 puan alır
  • Eğer bir küçük harf içeriyorsa 5 puan alır, birden fazla küçük harf içeriyorsa 10 puan alır
  • Eğer bir büyük harf içeriyorsa 5 puan alır, birden fazla büyük harf içeriyorsa 10 puan alır
  • Eğer harf ve rakam dışında karakter içeriyorsa 5 puan alır, birden fazla karakter içeriyorsa 10 puan alır

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;

  • 0 – 49 : Kabul edilemez
  • 50 – 59 : Zayıf
  • 60 – 79 : Normal
  • 80 – 89 : Güçlü
  • 90-100 : Güvenli

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;
	}
}

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;

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

XNA Oyunu / Çanakkale Geçilmez – 2

27 June 2011 Yorum yapılmamış

XNA ile Oyun Programlama serimize, daha önce başlayıp tamamlamadığımız Çanakkale Geçilmez oyununu tamamlayarak devam ediyoruz.

Bu yazıyı okumadan önce XNA konusunda diğer makaleler için XNA kategorisine bir göz atmanızı tavsiye ederim.

Düşman gemilerine yaptığımız atış miktarını ve isabet adedini tutacağımız iki değişkeni sınıf seviyesinde tanımlayalım;

int SKOR_ATIS = 0;
int SKOR_PUAN = 0;

Oyuna, düşman gemileri ve düşman gemilerine atacağımız gülleler eklemek için, sınıf seviyesinde GameObject sınıfında diziler oluşturacağız;

public GameObject[] Gemiler;
public GameObject[] Gulleler;

Ayrıca, düşman gemilerine ve onlara atacağımız güllelere sınırlama getirmek için iki sabiti (const) sınıf seviyesinde tanımlıyoruz;

public const int DUSMAN_ADET = 3;
public const int GULLE_ADET = 6;

Bu sayede, oyunun zorluk derecesini değiştirebilmek için iki alanımız oluyor; aynı anda savaşacağımız düşman gemisi adedi ve onlara atabileceğimiz gülle adedi. Aynı anda attığımız güllelerden bir tanesi hedefi bulmadan veya ekran dışına çıkmadan yeni gülle atamıyoruz.

Bu oyunda, düşman gemisi adedini 3 olarak, onlara aynı anda atabileceğimiz gülle adedini de 6 olarak belirledik.

LoadContent() methodunda bu değişkenlere başlangıç değerlerini atamalıyız;

Gemiler = new GameObject[DUSMAN_ADET];
for (int iLoop = 0; iLoop < DUSMAN_ADET; iLoop++)
{
	Gemiler[iLoop] = new GameObject(Content.Load<Texture2D>("DusmanGemi"));
}

Gulleler = new GameObject[GULLE_ADET];
for (int iLoop = 0; iLoop < GULLE_ADET; iLoop++)
{
	Gulleler[iLoop] = new GameObject(Content.Load<Texture2D>("Gulle"));
}

Update() method'unda boşluk tuşuna (Space) basılınca gülle atılmasını sağlayacak methodu çağıracak kodu ekliyoruz;

if (pks.IsKeyDown(Keys.Space) && ks.IsKeyUp(Keys.Space))
	GulleAtesle();

GulleAtesle() method’unda 6 gülle’nin herbirine tek tek bakarak, ekranda olmayan var mı kontrol ediyoruz.

Eğer o anda ekranda olmayan bir gülle bulursak (IsAlive özelliğinin false değer içermesinden) düşman gemisine doğru fırlatıyoruz.

Fırlatma işlemini yaparken güllenin fırlatma anındaki yeri ve fırlatma güzergahına dikkat etmeliyiz.

Güllenin Position özelliğine Top’umuzun X ve Y eksenindeki yerini veriyoruz, böylece, gülle tam olarak top’umuzun ucundan fırlatılacak.

Velocity özelliği ile güllenin güzergahını belirliyoruz; Top’umuzun baktığı açının sinus‘unu ve kosinus‘unu alarak, hız sabiti olan 5 değeri ile çarpıyoruz.

Not : Top’umuz ekranın altında, gemiler üstünde olduğu için Y eksenindeki hız sabitini -1 ile çarpıp, -5 değerini elde ediyoruz.

Ayrıca, SKOR_ATIS değişkeninin değerini de bir yükseltiyoruz.

private void GulleAtesle()
{
	foreach (GameObject Gulle in Gulleler)
	{
		if (!Gulle.IsAlive)
		{
			SKOR_ATIS++;
			Gulle.IsAlive = true;
			Gulle.Position = new Vector2(Top.Position.X - Gulle.Center.X, Top.Position.Y);
			Gulle.Velocity = new Vector2((float)Math.Sin(Top.Rotation) * 5, (float)Math.Cos(Top.Rotation) * -5);
			break;
		}
	}
}

Böylece, her boşluk (Space) tuşuna basıldığında 6 gülleden birisi topumuzun ucundan düşman gemisine doğru gönderilecektir. Eğer o anda ekranda 6 gülle varsa, gülle gönderilmeyecektir.

Update() method’unda, düşman gemilerini de yönetiyoruz;

foreach (GameObject Gemi in Gemiler)
{
	if (Gemi.IsAlive)
	{
		Gemi.Position += Gemi.Velocity;

		if (Gemi.Position.X < 0)
			Gemi.IsAlive = false;
	}
	else
	{
		Gemi.IsAlive = true;
		Gemi.Position = new Vector2(PENCERE_GENISLIK, MathHelper.Lerp(0, (float)(PENCERE_YUKSEKLIK * 0.6), (float)Rastgele.NextDouble()));
		Gemi.Velocity = new Vector2(MathHelper.Lerp(-2, -4, (float)Rastgele.NextDouble()), 0);
	}
}

Tüm düşman gemileri (DUSMAN_ADET sabitinden dolayı 3 adet) içerisinde dönen bir foreach döngüsü ile ilgili düşman gemisinin o anda hayatta olup/olmadığına bakıyoruz;

Eğer hayatta ise; gemi'nin yerini, gidiş yönünde hızı kadar ilerletiyoruz. Eğer gemi'nin yeni yeri pencere dışında ise, bir sonraki ekran güncellemesinde gemi'yi tekrar kullanabilmek için öldürüyoruz.

Eğer hayatta değilse; Gemi'yi ekrana çıkartabilmek için hayatta durumuna getiriyoruz, rastgele bir yer ve hız veriyoruz.

Rastgele yer belirlerken, pencerenin en üstünden itibaren %60'lık kısmını kullanıyoruz.

Rastgele hız belirlerken, MathHelper sınıfının Lerp() methodundan faydalanıyoruz.

Lerp() method'u, 3 parametre alır;

  • Değer 1 (Kaynak değer)
  • Değer 2 (Kaynak değer)
  • Büyüklük (0 ile 1 arası değer, Değer 2'nin ağırlığı)

Büyüklük parametresine 0 değer vermek, Değer 1'i, 1 değer vermek, Değer 2'yi döndürür.

Biz bu örnek'te düşman gemilerinin ekranın sağında belirmesi ve ekranın soluna doğru ilerlemesi için, -2 ve -4 arası hız'a sahip olmalarını sağladık.

Update() method'unda, ekrandaki gülleleri de yönetiyoruz;

foreach (GameObject Gulle in Gulleler)
{
	if (Gulle.IsAlive)
	{
		Gulle.Position += Gulle.Velocity;
		if (!Pencere.Contains(Gulle.TextureRectangle))
			Gulle.IsAlive = false;

		foreach (GameObject Gemi in Gemiler)
		{
			if (Gemi.TextureRectangle.Contains(Gulle.TextureRectangle))
			{
				SKOR_PUAN++;
				GemiVurulduSes.Play();
				Gemi.IsAlive = false;
				Gulle.IsAlive = false;
				break;
			}
		}
	}
}

Sadece hayatta olan güllelere teker teker bakıyoruz; (GULLE_ADET sabitinden dolayı en fazla 6 adet)

Gülle’nin yerini, hızı ve doğrultusu kadar ilerletiyoruz. Eğer pencere dışına çıktı ise, gülle’yi öldürüyoruz.

Hayatta olan her gülle için, hayatta olan her gemi ile çarpışma testi yapıyoruz. Eğer ilgili gülle gemi’lerden bir tanesi ile çarpışıyorsa, gülle’yi ve gemi’yi öldürüp, SKOR_PUAN değişkenini bir yükseltiyoruz.

Draw() method’unda, Arkaplan, Top, hayatta olan gemiler ve hayatta olan gülleleri ekrana çizdiriyoruz;

GraphicsDevice.Clear(Color.CornflowerBlue);

spriteBatch.Begin(SpriteBlendMode.AlphaBlend);

spriteBatch.Draw(Arkaplan, Pencere, Color.White);

spriteBatch.Draw(Top.Texture, Top.Position, null, Color.White, Top.Rotation, Top.Center, 1, SpriteEffects.None, 0);

foreach (GameObject Gemi in Gemiler)
{
	if (Gemi.IsAlive)
	{
		spriteBatch.Draw(Gemi.Texture, Gemi.Position, Color.White);
	}
}

foreach (GameObject Gulle in Gulleler)
{
	if (Gulle.IsAlive)
	{
		spriteBatch.Draw(Gulle.Texture, Gulle.Position, Color.White);
	}
}

Skor tablosunu çizdirebilmek için, sınıf seviyesinde iki yeni değişken eklememiz lazım;

Texture2D Karakterler;
Texture2D Sayilar;

LoadContent() method’unda bu değişkenlere değer atıyoruz;

Karakterler = Content.Load("Karakterler");
Sayilar = Content.Load("Sayilar");

Karakterler imajı’nın (0, 0) noktasından itibaren (113, 25) büyüklüğündeki alanı arasında kalan kısmı ekrana çizdirmek için, Draw() method’una;

spriteBatch.Draw(Karakterler, new Vector2((float)(PENCERE_GENISLIK * 0.05), (float)(PENCERE_YUKSEKLIK * 0.90)), new Rectangle(0, 0, 113, 25), Color.White);

Karakterler imajı’nın (0, 25) noktasından itibaren (113, 25) büyüklüğündeki alanı arasında kalan kısmı ekrana çizdirmek için, Draw() method’una;

spriteBatch.Draw(Karakterler, new Vector2((float)(PENCERE_GENISLIK * 0.75), (float)(PENCERE_YUKSEKLIK * 0.90)), new Rectangle(0, 25, 113, 25), Color.White);

Atış adedimizi ve Skor adedimizi ekrana çizdirmek için gerekli method çağrılarını (DrawAtis(), DrawSkor()) Draw() method’unda yapıyoruz.

private void DrawAtis()
{
	string Atis = SKOR_ATIS.ToString();
	for (int iLoop = 0; iLoop < Atis.Length; iLoop++)
	{
		int Rakam = Convert.ToInt32(Atis.Substring(iLoop, 1));
		spriteBatch.Draw(Sayilar, new Vector2((float)(PENCERE_GENISLIK * 0.05) + (23 * iLoop) + 120, (float)(PENCERE_YUKSEKLIK * 0.90)), new Rectangle(Rakam * 23, 0, 23, 25), Color.White);
	}
}

private void DrawSkor()
{
	string Atis = SKOR_PUAN.ToString();
	for (int iLoop = 0; iLoop < Atis.Length; iLoop++)
	{
		int Rakam = Convert.ToInt32(Atis.Substring(iLoop, 1));
		spriteBatch.Draw(Sayilar, new Vector2((float)(PENCERE_GENISLIK * 0.75) + (23 * iLoop) + 120, (float)(PENCERE_YUKSEKLIK * 0.90)), new Rectangle(Rakam * 23, 0, 23, 25), Color.White);
	}
}

Böylece, oyunumuzun kodlamasını bitirmiş olduk.

XNA ile Oyun Programlama - Çanakkale Geçilmez Oyunu

Oyunu tüm kodlarını buradan indirebilirsiniz.

Euler – 6

27 September 2010 Yorum yapılmamış

Euler serisinin altıncı yazısında, Project Euler’in 6. sorusunu çözeceğiz;

Orjinal Soru; The sum of the squares of the first ten natural numbers is,
12 + 22 + … + 102 = 385

The square of the sum of the first ten natural numbers is,
(1 + 2 + … + 10)2 = 552 = 3025

Hence the difference between the sum of the squares of the first ten natural numbers and the square of the sum is 3025 – 385 = 2640.

Find the difference between the sum of the squares of the first one hundred natural numbers and the square of the sum.

Türkçesi; İlk 10 sayının karelerinin toplamı,
12 + 22 + … + 102 = 385

İlk 10 sayının toplamlarının karesi,
(1 + 2 + … + 10)2 = 552 = 3025

İlk 10 sayı için toplamların karesi ile karelerin toplamı arasındaki fark; 3025 – 385 = 2640’tır.

İlk 100 sayının toplamların karesi ile karelerin toplamı arasındaki farkı bulunuz.

Önce siz çözmeyi deneyin, çözemezseniz Devamını oku…

C# Windows tarzı dosya boyutu formatlayıcı

04 September 2010 1 yorum

Eğer uygulamalarınızda dosya sistemindeki dosyalar veya dizinler ile uğraşıyorsanız (listeleme, filtreleme, vs.) büyük ihtimalle dosya veya dizinlerin boyutlarını hespalayan bir yönteminiz vardır.

Genellikle (kolay olduğundan ötürü) byte cinsinden dosya boyutunu 1000’e (bin) böler kilobyte cinsinden veya 1.000.000’a (milyon) böler megabyte cinsinden karşılığını buluruz.

Fakat Windows işletim sisteminde dosya veya dizinlerin boyutları en yakın birime göre hesaplanır ve gösterilir.

Küçük dosyalar byte, kilobyte veya megabyte cinsinden gösterilirken, daha büyük dosyalar gigabyte hatta terabyte cinsinden gösterilebiliyor.

Eğer biz de uygulamamızda dosya boyutlarını Windows tarzında göstermek istiyorsak, öncelikle birimleri elde etmemize yarayacak bir enum tanımlamalıyız;

public enum Boyutlar
{
	byte,
	kilobyte,
	megabyte,
	gigabyte,
	terabyte,
	petabyte
}

Daha sonra, parametre olarak noktalı rakam alan, geriye string döndüren bir method tanımlamalıyız;

public static string FormatDosyaBoyutu(decimal DosyaBoyutu)
{
}

FormatDosyaBoyutu method’unda, önce Boyutlar enum‘ından bir örnek oluşturacağız ve byte değerini içermesini sağlayacağız;

Boyutlar BoyutTanim = Boyutlar.byte;

Daha sonra bir döngü aracılığıyla, DosyaBoyutu değişkeni 1000’e bölünebildiği sürece BoyutTanim değişkeninin bir üst birimi içermesini sağlayacağız;

while (Math.Round(DosyaBoyutu) >= 1000)
{
	DosyaBoyutu /= 1024;
	BoyutTanim++;
}

Son olarak, method’dan geriye DosyaBoyutu değişkenin virgülden sonra 2 hane içeren ve doğru birimi gösteren değeri döndürmesini sağlayacağız;

return string.Format("{0}\t{1}", DosyaBoyutu.ToString("f2"), BoyutTanim);

Dosya Boyutu Formatlayıcı

Örnek kodun tamamı;

using System;
using System.Text;

namespace DosyaBoyutuFormatlayici
{
	class Program
	{
		public enum Boyutlar
		{
			byte,
			kilobyte,
			megabyte,
			gigabyte,
			terabyte,
			petabyte
		}

		public static void Main(string[] args)
		{
			Console.WriteLine(FormatDosyaBoyutu(0));
			Console.WriteLine(FormatDosyaBoyutu(10));
			Console.WriteLine(FormatDosyaBoyutu(200));
			Console.WriteLine(FormatDosyaBoyutu(3000));
			Console.WriteLine(FormatDosyaBoyutu(40000));
			Console.WriteLine(FormatDosyaBoyutu(500000));
			Console.WriteLine(FormatDosyaBoyutu(6000000));
			Console.WriteLine(FormatDosyaBoyutu(70000000));
			Console.WriteLine(FormatDosyaBoyutu(800000000));
			Console.WriteLine(FormatDosyaBoyutu(9000000000));
			Console.WriteLine(FormatDosyaBoyutu(10000000000));
			Console.WriteLine(FormatDosyaBoyutu(200000000000));
			Console.WriteLine(FormatDosyaBoyutu(3000000000000));
			Console.WriteLine(FormatDosyaBoyutu(40000000000000));
			Console.WriteLine(FormatDosyaBoyutu(500000000000000));
			Console.WriteLine(FormatDosyaBoyutu(6000000000000000));
			Console.WriteLine(FormatDosyaBoyutu(70000000000000000));
			Console.WriteLine(FormatDosyaBoyutu(800000000000000000));
			Console.WriteLine(FormatDosyaBoyutu(9000000000000000000));
			Console.WriteLine(FormatDosyaBoyutu(10000000000000000000));

			Console.ReadLine();
		}

		public static string FormatDosyaBoyutu(decimal DosyaBoyutu)
		{
			Boyutlar BoyutTanim = Boyutlar.byte;

			while (Math.Round(DosyaBoyutu) >= 1000)
			{
				DosyaBoyutu /= 1024;
				BoyutTanim++;
			}

			return string.Format("{0}\t{1}", DosyaBoyutu.ToString("f2"), BoyutTanim);
		}
	}
}