30 Nisan 2014 Çarşamba

JAVA Soket Programlama Türkçe Karakter Çözümü

Soket programlamada sıkıntılardan bir tanesi de iki makine arasında türkçe karakterlerin düzgün bir şekilde gönderilmesidir.



 Socket client;
 BufferedReader in = new BufferedReader(new client.getInputStream(), "UTF-8"));




ile çözülebilir.

19 Nisan 2014 Cumartesi

JAVA AES Şifreleme ile Single-Multiple Thread Programlama Benchmark Çalışması



Bu çalışma sonucunda tek threadle ve çok threadle programlanmış uygulamanın çalışma performansını göreceğiz.
Çalışmada AES şifreleme kullanılmıştır.Şifreleme algoritmaları işlemcileri ziyadesiyle zorlayan ve bir o kadar da bilgi güvenliği için önem arz eden algoritmalar bütünüdür.
AES , Amerikan hükümetinin katkılarıyla geliştirilmiş bir defacto şifreleme standardıdır[1].Simetrik anahtarlama tekniğiyle çalışmaktadır.Yani hem şifreleme hem de şifreyi çözmek için aynı anahtar kullanılmaktadır.

AES,blok şifrelemeyle çalışmaktadır.Moduna göre(128,256 bit) veriyi blok halinde alıp şifreler.Çok thread yapısı kullanılarak şifreleme süresi kısaltılabilinir.
Buradaki çalışma AES şifrelemede tek ve çok thread li çalışmayı göstereceğiz.Şifrelemede kullanılacak API için [2] adresindeki Parallel Java Library kullanılmıştır.
Süre ölçümünde sadece şifreleme kısmı esas alınmıştır.Her iki modda da  şifrelenecek verinin hazırlanma aşamaları aynıdır. 


İlk başta her iki modda şifreleme için gerekli temel metodlar yazılmıştır.Bu metodlar içerisinde şifrelemede kullanılacak dosya boyutu ve şifrelemede kullanılacak nesnelerin ilklendirmeleri yapılmıştır.
Şifrelemede kullanılacak dosya boyutu yaklaşık 4 MB büyüklüğündedir.AES-256 bit şifreleme ve ECB modunda şifreleme yapılmıştır.





package payalan;



/**

 * Programda kullanilan temel fonksiyonlar ve ilklendirlmeler burada yer

 * almaktadir.

 * 

 * @author 11000

 */

import edu.rit.crypto.blockcipher.AES256Cipher;

public class CKernel
{
    static long          startTime, stopTime, measuredTime;
    static String        key                   = "b661ca5d5df7e4e66944751923247a91c1632bf1dc5821a5cd8d83fd4d8d439f"; //256 bit key.    
    static byte[]        byteKey               = edu.rit.util.Hex
                                                       .toByteArray(key);                                           //String -> Byte conversion.
    private AES256Cipher cipher;
    static int           plainByteSize         = 4194304;
    static int           parallelPlainByteSize = 65536;
    
    public AES256Cipher getCipher()
    {
        return cipher;
    }
    
    public void setCipher(AES256Cipher cipher)
    {
        this.cipher = cipher;
    }
    
    public CKernel()
    {
        setCipher(new AES256Cipher(byteKey));
        
    }
    
}


Tek threadli şifreleme kısmında bütün akış tek bir metodunun içinde gerçekleşmiştir.

package payalan;

/**
 * Tek proses,tek thread ile sifreleme yapmaktadir.Giris olarak veri buyuklugu
 * yaklasik 4 MB civarindadir. Program calistirildiktan sonra sifrelenmis
 * dosyanin buyuklugu ve sifreleme suresini gosteren cikti gonderir.
 * 
 * @author 11000
 */
import java.security.SecureRandom;
import java.util.ArrayList;

public class CSequentalEncryption extends CKernel
{
    
    public void encrypt()
    {
        System.out.println("AES ENCRYPTION WITH SEQUENTAL WORKFLOW........");
        byte[] encBytes = new byte[16]; //sifreleme oncesi gelen buyuk veriyi parcalamada kullanilan kucuk 16 byte blok.
        ArrayList<byte[]> encryptedValue = new ArrayList<>(); //sifrelenmiş parcali verilerin bir ArrayList te tutulmasi.
        SecureRandom sec = new SecureRandom();
        byte[] source = sec.generateSeed(plainByteSize);
        //        System.out.println("Data size = " + source.length + " byte");
        int index = 0;
        startTime = System.currentTimeMillis();
        while (index < source.length)
        {
            System.arraycopy(source, index, encBytes, 0,
                    Math.min(source.length, 16));
            //            System.out.println(Hex.encodeHexString(encBytes));
            getCipher().encrypt(encBytes);
            encryptedValue.add(encBytes);
            index = index + 16;
        }
        stopTime = System.currentTimeMillis();
        //--------------------------------
        measuredTime = stopTime - startTime;
        System.out.println("Passed time =" + measuredTime + " ms");
    }
    
}
Java thread için Runnable arayüzünden(interface) implement işlemi yapılmıştır.Thread sayısı 10 seçilmiştir.Bu threadlerin planlaması(scheduling) JVM tarafından sağlanmaktadır.

package payalan;

/**
 * Tek proses,multithreaded bir yapida sifreleme yapmaktadir.Thread sayisi
 * statik bir degiskende tutulmaktadir.Giris verisi yaklasik 4 MB buyuklugunde
 * olmaktadir.
 * 
 */
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class CJavaThreadedEncryption extends CKernel implements Runnable
{
    
    byte[]                   encBytes       = new byte[16];                   //sifreleme oncesi gelen buyuk veriyi parcalamada kullanilan kucuk 16 byte blok.
    ArrayList<byte[]>        encryptedValue = new ArrayList<>();              //sifrelenmiş parcali verilerin bir ArrayList te tutulmasi.
    SecureRandom             sec            = new SecureRandom();
    byte[]                   source         = sec.generateSeed(plainByteSize); //sifrelenmeye hazirlanacak giris verisi burada olusturulmaktadir.
    int                      index          = 0;                              //Giris(plain) veriyi bloklar halinde parcalamak icin kullanilacak pointer index degiskenidir.
    private static final int NTHREDS        = 10;                             //Olusturulan thread sayisi.
                                                                               
    @Override
    public void run()
    {
        
        getCipher().encrypt(encBytes);
        //        System.out.println("Encrypted text = " + Hex.encodeHexString(encBytes));
        encryptedValue.add(encBytes);
        
    }
    
    public void encrypt()
    {
        //        System.out.println("Data size = " + source.length + " byte");
        System.out
                .println("AES ENCRYPTION WITH JAVA THREADED WORKFLOW........");
        ExecutorService executor = Executors.newFixedThreadPool(NTHREDS);
        startTime = System.currentTimeMillis();
        while (index < source.length)
        {
            System.arraycopy(source, index, encBytes, 0,
                    Math.min(source.length, 16));
            executor.execute(this);
            index = index + 16;
        }
        executor.shutdown();
        stopTime = System.currentTimeMillis();
        measuredTime = stopTime - startTime;
        System.out.println("Elapsed time=" + measuredTime + " ms");
    }
    
}

Yazılan kodlar yeni bir CTest nesnesi içerisinde çalıştırılmıştır.

package payalan;

/**
 * Uygulama AES sifreleme teknigini iki farkli performansta sifreleme yapar.
 * 1-CSequentalEncryption Tek proses,tek thread de sifreleme yapar.
 * 2-CJavaThreadedEncryption Tek proses,multithreaded şifreleme yapar.Thread
 * sayisi CJavaThreadedEncryption sinifinin icinde tanimlidir.
 * 
 * @author 11000
 * 
 */
public class CTest
{
    static CSequentalEncryption        seqenc           = new CSequentalEncryption();
    static CJavaThreadedEncryption     javaThreaded     = new CJavaThreadedEncryption();
    static CParallelThreadedEncryption parallelThreaded = new CParallelThreadedEncryption();
    
    public static void main(String args[]) throws Exception
    {
        seqenc.encrypt();
        javaThreaded.encrypt();
    }
    
}


Programın sonucunda oluşan çıktılar aşağıdaki gibidir.Görüldüğü üzere çok thread ile programlanmış uygulamalar daha hızlı çalışmaktadır.

CTest.java nın çıktısı.

AES ENCRYPTION WITH SEQUENTAL WORKFLOW........
Passed time =174 ms
AES ENCRYPTION WITH JAVA THREADED WORKFLOW........
Elapsed time=75 ms






[1]http://tr.wikipedia.org/wiki/AES
[2]http://www.cs.rit.edu/~ark/pj.shtml