NLog ile Loglama

Öncelikle projeye sağ tıklayıp “Manage NuGet Packages…” diyoruz. Oradan NLog’u bulup projeye ekliyoruz. Loglama yapacağımız sınıfın içine aşağıdaki satırı ekliyoruz.

private static Logger logger = LogManager.GetCurrentClassLogger();

NLog nereye, nasıl loglayacağını config dosyasından algılıyor. Bunun için NLog.config adında bir xml dökümanı oluşturuyoruz. Dosyanın Visual Studio üzerinden özellikleri Build Action:Content ve Copy To Output Directory:Copy if newer şeklinde olmalı.

<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <targets>
    <target name="file" xsi:type="File" fileName="test.log" layout="${longdate}|${level:uppercase=true}|${logger}|${message}|${exception:format=tostring}"/>
    <target name="eventLog" xsi:type="EventLog" layout="${longdate}|${level:uppercase=true}|${logger}|${message}|${exception:format=tostring}"/>
  </targets>
  <rules>
    <logger name="*" writeTo="file"/>
    <logger name="*" writeTo="eventLog"/>
  </rules>
</nlog>

Yukarıdaki örnek konfigurasyon hem test.log adlı dosyaya hem de Windows Olay Görüntüleyicisi’ne kayıt atmaktadır. Sadece dosyaya log atmasını istersek rules altındaki ikinci sıradaki  logger’ı silmek yeterlidir.  Konfigurasyon ile ilgili daha fazla bilgiyi https://github.com/nlog/nlog/wiki/Configuration-file adresinden alabilirsiniz.

İstediğimiz metodun içine aşağıdaki örnek satırı ekleyerek log atabiliyoruz.

logger.Log(LogLevel.Debug, "Test");

veya exception loglamak istersek;

logger.LogException(LogLevel.Debug, "Mesaj", exception);

Paralel System.Random

Paralel uygulamalarda çeşitli yerlerde rastgeleliğe ihtiyaç duyabiliriz. Rastgeleliğin, şifreleme seviyesinde güçlü olmasının gerekmediği durumlarda System.Random kullanmak hızlı ve iyi bir seçimdir, fakat paralel kullanımlarda çok iyi sonuçlar vermez. Bu gibi durumlarda aşağıdaki sınıf kullanılabilir.

using System;
using System.Collections;
using System.Collections.Generic;

namespace Core.Utilities
{
    /// <summary>Parallel safe version of System.Random</summary>
    public static class RandomGen
    {
        private static readonly Random Global = new Random();

        [ThreadStatic]
        private static Random _local;

        /// <summary>Returns a nonnegative random number.</summary>
        public static int Next()
        {
            var inst = _local;

            if (inst == null)
            {
                int seed;

                lock (Global) seed = Global.Next();

                _local = inst = new Random(seed);
            }

            return inst.Next();
        }

        /// <summary>Returns a nonnegative random number less than the specified minimum.</summary>
        public static int Next(int maxValue)
        {
            var inst = _local;

            if (inst == null)
            {
                int seed;

                lock (Global) seed = Global.Next();

                _local = inst = new Random(seed);
            }

            return inst.Next(maxValue);
        }

        /// <summary>Returns a random number within a specified range.</summary>
        public static int Next(int minValue, int maxValue)
        {
            var inst = _local;

            if (inst == null)
            {
                int seed;

                lock (Global) seed = Global.Next();

                _local = inst = new Random(seed);
            }

            return inst.Next(minValue, maxValue);
        }

        /// <summary>Returns a random element from a list.</summary>
        public static T Next<T>(IList<T> list)
        {
            var inst = _local;

            if (inst == null)
            {
                int seed;

                lock (Global) seed = Global.Next();

                _local = inst = new Random(seed);
            }

            return list[inst.Next(0, list.Count)];
        }

        /// <summary>Returns a random number between 0.0 and 1.0.</summary>
        public static double NextDouble()
        {
            var inst = _local;

            if (inst == null)
            {
                int seed;

                lock (Global) seed = Global.Next();

                _local = inst = new Random(seed);
            }

            return inst.NextDouble();
        }

        /// <summary>Fills the elements of a specified array of bytes with random numbers.</summary>
        public static void NextBytes(byte[] buffer)
        {
            var inst = _local;

            if (inst == null)
            {
                int seed;

                lock (Global) seed = Global.Next();

                _local = inst = new Random(seed);
            }

            inst.NextBytes(buffer);
        }
    }
}

Erişim Belirleyiciler

Erişim belirleyiciler bir üyeye veya tipe erişimi belirleyen anahtar kelimelerdir. Dört adet erişim belirleyici vardır.

  • public
  • protected
  • internal
  • private

Bunları kullanarak beş çeşit erişim seviyesi tanımlayabiliriz.

public: Erişim sınırlı değildir.

protected: Erişim, içeren sınıf veya içeren sınıftan türetilen tipler ile sınırlıdır.

internal: Erişim geçerli derleme ile sınırlıdır.

protected internal: Erişim, geçerli derleme veya  içeren sınıftan türetilen tipler ile sınırlıdır.

private: Erişim içeren tip ile sınırlıdır.

Wolfram Alpha ile Doğruluk Tablosu Hesaplama

Diyelim ki 3 adet mantıksal değişkeniniz(A, B, C) var ve bunlardan sadece biri “doğru” olduğunda sonucun(Q) “doğru” olmasını istiyorsunuz. Bu problemi çözebilmek için önce doğruluk tablosunu oluşturuyoruz.

A B C Q
0 0 0 0
0 0 1 1
0 1 0 1
0 1 1 0
1 0 0 1
1 0 1 0
1 1 0 0
1 1 1 0

Q ‘ nun 1 olduğu satırlardaki A, B ve C çarpımlarını topluyoruz.

Q = A’ B’ C + A’ B C’ + A B’ C’

Bunu sadeleştirmek için en hızlı yol WolframAlpha‘ya göndermek.

(NOT A) AND (NOT B) AND C OR (NOT A) AND B AND (NOT C) OR A AND (NOT B) AND (NOT C) şeklinde yazıyoruz ve en sade şeklini elde ediyoruz.

Q = (A AND B AND C)  XOR A XOR B XOR C

override ve new

Bu yazıda override ve new sözcüklerinin ne işe yaradığını öğreneceğiz. Hepimizin bildiği gibi sınıflar kalıtım ile birbirinden türetilebilir. Türetilen sınıf, türediği sınıfın tüm özelliklerini kalıtım yolu ile devralır. Devralınan metotları farklı bir biçimde kullanmak istiyorsak bunu override ile yapabiliriz. Devralınan metotla aynı isimde fakat farklı bir metot tanımlamak istersek bunu new ile yapabiliriz. Aşağıdaki örneği çalıştırdığımızda program ekrana alt alta iki kere B yazdırmaktadır.

using System;

namespace ConsoleApplication1
{
    public class A
    {
        public virtual void Display()
        {
            Console.WriteLine("A");
        }
    }

    public class B : A
    {
        public override void Display()
        {
            Console.WriteLine("B");
        }
    }

    public class C : B
    {
        public new void Display()
        {
            Console.WriteLine("C");
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            A a = new B();
            a.Display();

            a = new C();
            a.Display();

            Console.ReadKey();
        }
    }
}

Dosya MD5 Hesaplama

MD5 (Message-Digest algorithm 5), veri bütünlüğünü test etmek için kullanılan, Ron Rivest tarafından 1991 yılında geliştirilmiş bir kriptografik özet (tek yönlü şifreleme) algoritmasıdır. Girdi, verinin boyutundan bağımsız olarak 128 bitlik özetler üretir.

Herhangi bir dosyanın MD5’ini almak için aşağıdaki metodu kullanabilirsiniz.

public static string GetMD5Hash(string fileName)
{
FileStream file = new FileStream(fileName, FileMode.Open);

MD5 md5 = new MD5CryptoServiceProvider();
byte[] retVal = md5.ComputeHash(file);
file.Close();

StringBuilder sb = new StringBuilder();
for (int i = 0; i < retVal.Length; i++) { sb.Append(retVal[i].ToString("x2")); } return sb.ToString(); } [/csharp]

Bilgisayar Tarihi

  • Univac Univac
  • Mark I Mark I
  • Eniac Eniac
  • Hactor Hactor
     

İlk Kuşak: Vakum Tüpleri (1942-1956)

ENIAC gibi ilk elektronik bilgisayarlar vakumlu tüp olarak bilinen teknolojiye dayanmaktadır. Bu kuşakta yazılım diye bir şey yoktu. Teknolojinin çoğu donanıma dayanıyordu.

İkinci Kuşak: Transistörler (1956-1963)

İkinci kuşak bilgisayarlarda vakum tüplerinin yerine yarı iletken materyallerden yapılan transistörler kullanıldı. Bu kuşak yazılım kavramını ortaya çıkarmıştır.

Üçüncü Kuşak: Entegre Devreler (1964-1971)

Bu kuşakta transistorlardan yonga (chip) adı verilen entegre devrelere geçildi. Yongalar içinde elektronik devreleri içeren küçük kare parçalardır. Genellikle silikondan ve ileri teknoloji kullanılarak üretilirler.

Dördüncü Kuşak: Mikro Devreler (1971-?)

1970’li yıllarda entegre devreler iyice küçülmeye devam etmiştir. Bu işlem büyük çapta tümleşme (very large scale entegration) olarak adlandırılmıştır.

Beşinci Kuşak:

Beşinci kuşak bilgisayarlar özellikle yeni teknolojilerin kullanıldığı ve buna bağlı olarak hızlı çalışan ve daha akıllı bilgisayarlar geliştirilecek. Yapay zekaya sahip olan bu bilgisayarlar yaşamımıza daha çok girecekler.

Triple DES Şifreleme

Elektronik ödeme sistemlerinde sıklıkla kullanılan TDEA(Data Encryption Algorithm) veya genel adıyla Triple DES şifreleme ve şifre çözme yapabilen java ve C# sınıfları aşağıdadır. Şifreleme işlemi yapıldıktan sonra veri Base64 kodlandığı için web servisleri üzerinden gönderilebilir.

package project1;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

import sun.misc.BASE64Encoder;
import sun.misc.BASE64Decoder;

public class TripleDes {

    public String encrypt(String message, String key) throws Exception {
        // Create secret key
        byte[] bKey = new byte[24];
        for (int i = 0; i < key.length() && i < bKey.length; i++) {
            bKey[i] = (byte)key.charAt(i);
        }
        SecretKey secretKey = new SecretKeySpec(bKey, "DESede");

        // Initialize encoder
        Cipher desCipher = Cipher.getInstance("DESede");
        desCipher.init(Cipher.ENCRYPT_MODE, secretKey);

        // Encode DESede
        byte[] byteCipherText = desCipher.doFinal(message.getBytes());

        // Encode BASE64 and return
        return new BASE64Encoder().encode(byteCipherText);
    }

    public String decrypt(String message, String key) throws Exception {
        // Create secret key
        byte[] bKey = new byte[24];
        for (int i = 0; i < key.length() && i < bKey.length; i++) {
            bKey[i] = (byte)key.charAt(i);
        }
        SecretKey secretKey = new SecretKeySpec(bKey, "DESede");

        // Initialize decoder
        Cipher desCipher = Cipher.getInstance("DESede");
        desCipher.init(Cipher.DECRYPT_MODE, secretKey, desCipher.getParameters());

        // Decode BASE64
        byte[] decodedMessage = new BASE64Decoder().decodeBuffer(message);

        // Decode DESede and return
        return new String(desCipher.doFinal(decodedMessage));
    }
}
using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;

namespace Project1
{
    internal static class TripleDes
    {
        internal static string Decrypt(string cipher, string key)
        {
            byte[] cipherBytes = Convert.FromBase64String(cipher);

            MD5CryptoServiceProvider md5Csb = new MD5CryptoServiceProvider();
            byte[] keyBytes = md5Csb.ComputeHash(Encoding.UTF8.GetBytes(key));

            string decryptedData;

            using (MemoryStream ms = new MemoryStream())
            {
                TripleDES tdes = TripleDES.Create();
                tdes.Key = keyBytes;
                tdes.Mode = CipherMode.ECB;
                using (CryptoStream cs = new CryptoStream(ms, tdes.CreateDecryptor(), CryptoStreamMode.Write))
                {
                    cs.Write(cipherBytes, 0, cipherBytes.Length);
                    cs.FlushFinalBlock();
                    byte[] messageBytes = ms.ToArray();
                    decryptedData = Encoding.UTF8.GetString(messageBytes);
                }
            }

            return decryptedData;
        }

        internal static string Encrypt(string message, string key)
        {
            byte[] messageBytes = Encoding.UTF8.GetBytes(message);

            MD5CryptoServiceProvider md5Csb = new MD5CryptoServiceProvider();
            byte[] keyBytes = md5Csb.ComputeHash(Encoding.UTF8.GetBytes(key));

            string encryptedData;
            using (MemoryStream ms = new MemoryStream())
            {
                TripleDES tdes = TripleDES.Create();
                tdes.Key = keyBytes;
                tdes.Mode = CipherMode.ECB;
                using (CryptoStream cs = new CryptoStream(ms, tdes.CreateEncryptor(), CryptoStreamMode.Write))
                {
                    cs.Write(messageBytes, 0, messageBytes.Length);
                    cs.FlushFinalBlock();
                    byte[] cipherBytes = ms.ToArray();
                    encryptedData = Convert.ToBase64String(cipherBytes);
                }
            }

            return encryptedData;
        }
    }
}