Bilgi Entropisi
53 gibi herhangi bir pozitif tamsayı
şeklinde 10’luk tabanda ifade edilebilir. Tabii ki bu sayıyı 2’lik gibi farklı tabanlarda da ifade edebiliriz. 53 sayısını ikilik tabanda 110101 olarak 6 hane ile ifade edebiliriz. Aynı zamanda
10’luk tabanda 53 sayısına eşittir.
Aklımdan tuttuğum sayıyı tahmin et oyunu oynadığımızı düşünürsek, ikilik tabanda 6 hane ile ifade edilen 53 (110101) sayısını tahmin etme şansınız nedir? 6 hanenin hepsini doğru bilmeniz gerektiğine göre her hanede
şansınız olduğu açıktır (0 veya 1). Toplam 6 hane için (Olasılık ve İstatistik dersinden hatırlayalım) 6 adet
‘nin çarpımı olan
, doğru tahminde bulunabileceğimiz olasılığı ifade eder. Kısaca doğru tahmin şansımızı
olarak hesaplarız.
haneli bir sayıyı tahmin etme şansımız
‘dir. Çünkü
hane ile en fazla
sayı üretilebilir. Tahminimiz ise bu sayılardan sadece birtanesidir. Peki bu durumda n haneli bir sayı için, bilgi teorisinde entropi olarak da ifade edilen bilinmezlik matematiksel olarak nasıl ifade edilebilir? Evet bilinmezliği
olarak ifade edebiliriz. Çünkü bilmediğimiz
hane vardır. Logaritmik olarak
olarak da ifade edebiliriz. Örneğimiz için entropy = log(mümkün olan sayı adedi) şeklinde bir formül elde ederiz.
Entropi, Shannon tarafından (Shannon, C. E., A mathematical theory of communication, Bell System Technical Journal, 27, 4 (1948) 379–423.) tanımlanan ve bilgi teorisinden gelen bir kavramdır. Entropi sistemde var olan belirsizliğin derecesini ölçer. Bir dizi ne kadar tahmin edilebilir ise o kadar fazla bilgi içermektedir. Bu yüzden bilgiyi gizlemenin yolu, tahmin edilebilirliği ortadan kaldırmaktır. Entropi yüksek rastgelelik, bilinmezlik ile açıklanır.
Örneğimiz üzerinden devam ediyoruz. 6 bit ile ifade edilen 53 (110101) sayısının herhangi bir hanesinin değerini örneğin 6. haneyi bildiğimizi varsayarsak entropi artık 6 değil 5’tir. Çünkü bilinmezliği ifade eden matematiksel değer azalmıştır. Tahmin şansımız daha da artmıştır. 6 olarak ifade edilen entropinin rastgeleliği azalmıştır. 6. haneyi bildiğimize göre bu hane bizim için artık lüzumsuzdur. Tahmin şansımız artık
olarak hesaplanır. Sayımızı ifade eden 6 hane arasında fonksiyonel bir bağımlılığın açığa çıkmaması da önemlidir. 5 haneyi biliyor olmamız bile 6. haneyi hesaplamamız için yeterli olmamalıdır. Sayımızı
bitler şeklinde ifade edersek,
şeklindeki bir bilgi hanelerin rastgele dizilmediğini ve bir hanenin diğerleri ile hesaplanabildiğini gösterir. Bu durum dizi elemanları arasında fonksiyonel bir bağlantı olduğunu gösterir ve az rastgelelik anlamına gelmektedir. Rastgelelik azaldıkça tahmin edilebilirlik artar.
Birbirinden bağımsız olarak her bir hanenin tahmin edilme olasılığının
olduğundan bahsetmiştik (0 ya da 1). Bir an için, elimizde bazı olasılıksal bilgilerin olduğunu ve dizideki elemanlardan her birinin, diğerlerinden bağımsız olarak
olma olasılığının
olduğunu varsayalım. Bu durumda entropi hala dizideki eleman sayısı olan
midir? Tahmin etme olasılığımız hala
midir? İşte bu problem ünlü bilgi teorisyeni Shannon tarafından çözülmüştür.
Elbette hala
haneli bir dizi için mümkün olan
dizi mevcuttur.
uzunluktaki bir dizi için her elemanın
olarak seçilme olasılığının
olduğu bir durumda,
‘lerin dizide görülme ortalaması
‘tir. Daha açık bir tabirle n elemanın ortalama
‘i
olarak görünür. Burada dikkat çekmek istediğim konu
‘lerin görülme olasılığının
‘den büyük ya da küçük olması entropiyi azaltır.
‘lerin görülme olasılığı düşüyorsa
‘ın ki artıyor demektir. Yani tahmin etme olasılığımız artıyor demektir. Entropi
‘lerin görülme olasılığının
olduğu durumda en yüksektir. Çünkü tüm elemanların
görülme olasılıkları eşittir ve elimizde tahminimizi kolaylaştıracak bir bilgi yok demektir. Diziyi biliyorsak entropi
olur. Yani belirsizlik sıfırdır.
Entropiyi
gibi bir fonksiyon olarak tanımlarsak( burada
örneğimizde
olarak kabul ettiğimiz görülme olasılığıdır), aşağıdaki grafik bize görülme olasılığı ile entropi arasındaki ilişkiyi gösterecektir.

1’lerin görülme olasılığının
olduğu bir durumda 1’lerin dizinin yaklaşık
‘ini oluşturduğu diziler tahminimiz için aday dizilerdir. Diğerleri ise aday olmayan dizilerdir. Her ne kadar aday dizilerimizin sayılarını düşürsekte (yani tahmin şansımızı artırsakta) sonuç hala aday diziler arasındaki tek bir dizidir. Örneğin
ve bitlerin görülme ortalamasının
olduğu bir örnekte aday dizilerimizden birinde dizi elemanlarının
tanesi
olarak seçilir ve bu bizim için doğru tahminler kümesinin bir elemanıdır. Peki
tane
içeren kaç tane dizi vardır?
İşte bu bilgi bize aday dizilerimizden birinin entropisini verir ve aşağıdaki Shannon fonksiyonu ile hesaplanır.
![]()
Burada
(q = 0’ın görülme ortalaması) ve logaritma
tabanındadır.
durumunda
yaklaşık olarak
ve
olur(100 ile çarptık çünkü her hane için aynı işlemi yapıp sonuçları topluyoruz). Entropi artık
değil
‘dir ve bilinmezlik yani entropi azalmıştır.
tanesi
olan 100 elemanlı dizi sayısı,
=
=
olarak hesaplanır. Tahmin kümemizdeki bir dizinin entropisi yani bilinmezliği artık 100 değil 81’dir deriz.
100 elemanlı bir dizide 1’lerin ortalama görünümünün 75 olduğu dizilerin sayısı aynı zamanda
binom katsayısı ile hesaplanabilir. Burada p 1’in görülme olasılığı ve n dizinin uzunluğudur. Böylece entropinin
olduğunuda buradan çıkarabiliriz.
Şimdiye kadar yaptığımız formal tanımları daha iyi pekiştirebilmek için, gerçek bir dünya örneği yapalım. Görsel bilgi içermesi açısından bir görüntünün ve şifrelenmiş halinin bilgi entropilerini beraberce hesaplayalım. Örneğimizde her bir pikseli 256 bit ile temsil edilen 256×256 boyutlarında gri seviye bir mandril görüntüsü (telif hakkı olmayan test amaçlı bir resim) kullanacağız. Şifreleme algoritmasının entropiyi artırıp artırmadığını, yani bilgiyi ortadan kaldırıp kaldırmadığını Shannon’un entropi yöntemiyle test edeceğiz. Ben 256 bit anahtar kullanan AES ile şifreleme yaptım. Sizler istediğiniz algoritmayı kullanabilirsiniz. Çünkü konumuz şifreleme algoritmasından bağımsız. Görüntünün düz ve şifreli hali aşağıda gösterilmiştir.

Shannon’un belirsizliği ölçen entropi ölçüm yönteminin genel formülü aşağıdaki gibidir.
(1) 
Burada N toplam sembol sayısını belirtmektedir ve resim şifrelemede piksel değerlerinin toplam sayısıdır. Bir pikselin
değerinde olma olasılığı
ile gösterilir. Eğer şifrelenmiş resmin entropisi logaritma N’ye yeterince yaklaşırsa, resmin histogramı yeterince düzgündür denilebilir. Gri bir resim için N, 256 yani
‘dir. Çünkü her biri 0..255 arasında değer alan piksellerden oluşur. Bir an için 0..255 arası değerlerin her birinin toplam pikseller üzerinde aynı olasılıkla bulunduğunu varsayalım.
değerlerinin her birini içeren piksel sayılarının aynı olduğu durumda entropi Shannon eşitliğine göre 8 olur. Bu durum gerçek rastgeleliği gösterir. Bu sayı ideal olan sayıdır. Ancak gerçekte şifrelenmiş bir görüntü tüm sembolleri aynı olasılıkta barındırmaz(Barındırması pikseller arasında fonksiyonel bağımlılık olduğunu gösterir mi ?). Güvenli bir şifreleme yöntemi ile entropi ideal olan 8’e yaklaşır. Örneğimizde, şifrelenmemiş düz resmin entropi değeri yaklaşık olarak 7.11, 256 bitlik anahtar ile şifrelenmiş görüntünün ise yaklaşık olarak 7.998 olarak hesaplanır (Farklı anahtarlarla yaklaşık değerler elde edilir). Hesaplama adımlarımız şu şekilde:
- Görüntünün histogramını hesapla
- Histogram bilgisinden her bir piksel değerinin (0-255 arası bu değerler) histogramda ne kadar bulunduğunu hesapla (örneğin 256×256 adet pikselin 120 tanesi 46 değerinde. Bu durumda 46 değerindeki piksellerin bulunma olasılığı 120/256×256 olur.)
- Shannon fonksiyonu ile her bir piksel değerinin entropisini hesapla
- Tüm piksel değerlerinin entropi değerlerini topla
Bilgi entropisi analizi şifreleme yöntemlerinin güvenlik analizlerinde kullanılan önemli analizlerden bir tanesidir. Bir şifreleme yönteminin orjinal metin üzerinde bir araya gelerek anlamlı bilgi oluşturan verilerin dağıtılması, ortadan kaldırılması ve mevcut desenlerin bozularak bilgi çıkarımı yapılamaması konularında ne kadar başarılı olduğunun test edilmesi için kullanılan bir yöntemdir aynı zamanda. Bu analiz ile bilgi miktarı ölçülerek, bilginin ortadan kaldırılıp kaldırılmadığı izlenebilir. Sayfanın altında örnek bir kod yazdım. Renkli görüntüler içinde kullanabilirsiniz. Ben sadece tek bir renk değeri için hesaplama yaptım(örneğimiz gri seviye olduğu için). Kodlar örnek amaçlıdır. Herhangi bir üründe kullanılmak için tamamen hazır halde (production-ready) değildir.
Bir sonraki yazımızda görüşmek üzere.
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Processing;
using System.IO;
using System.Runtime.CompilerServices;
using System.Security.Cryptography;
using System.Text;
Console.WriteLine("***Information Entropy of An 256x256 Image***");
string EncrFolder = Path.Combine(Environment.CurrentDirectory, "Encrypted");
string DecrFolder = Path.Combine(Environment.CurrentDirectory, "Decrypted");
string orgImage = Path.Combine(Environment.CurrentDirectory, "baboon.bmp");
EncryptImageAndCalculateEntropy();
//DecryptImage();
void EncryptImageAndCalculateEntropy()
{
using (Image<Rgb24> image = Image.Load<Rgb24>(orgImage))
{
image.Mutate(x => x
.Resize(256, 256)
.Grayscale());
Console.WriteLine($"Entropy of the Plain Image is: {ImageEntropy.CalculateEntropy(image)}");
byte[] pixelBytes = new byte[image.Width * image.Height * Unsafe.SizeOf<Rgb24>()];
image.CopyPixelDataTo(pixelBytes);
byte[] encrBytes = EncryptionClass.Encrypt(pixelBytes, password: "myPassword");
using (var encrImage = Image.LoadPixelData<Rgb24>(encrBytes, image.Width, image.Height))
{
encrImage.Save(Path.Combine(EncrFolder, "encrBaboon.bmp"));
Console.WriteLine($"Entropy of the Encrypted Image is: {ImageEntropy.CalculateEntropy(encrImage)}");
}
}
}
void DecryptImage()
{
using (Image<Rgb24> image = Image.Load<Rgb24>(Path.Combine(EncrFolder, "encrBaboon.bmp")))
{
byte[] pixelBytes = new byte[image.Width * image.Height * Unsafe.SizeOf<Rgb24>()];
image.CopyPixelDataTo(pixelBytes);
byte[] decrBytes = EncryptionClass.Decrypt(pixelBytes, password: "myPassword");
using (var decrImage = Image.LoadPixelData<Rgb24>(decrBytes, image.Width, image.Height))
{
decrImage.Save(Path.Combine(DecrFolder, "decrBaboon.bmp"));
}
}
}
/// <summary>
/// The <c>ImageEntropy</c> class.
/// Contains all methods for calculating information entropy of an image.
/// </summary>
public class ImageEntropy
{
public static double CalculateEntropy(Image<Rgb24> image)
{
var imageHistogram = ImageHistogram(image);
double entropi = 0;
for (int i = 0; i < 256; i++)
{
if (imageHistogram.red[i] == 0)
continue;
else //Shannon function
entropi += CalculateProbability(imageHistogram.red[i], imageHistogram.red) * Math.Log((1 / CalculateProbability(imageHistogram.red[i], imageHistogram.red)), 2);
}
return entropi;
}
static (int[] red, int[] green, int[] blue) ImageHistogram(Image<Rgb24> image)
{
//histogram arrays of the pixel values
int[] red = new int[256];
int[] green = new int[256];
int[] blue = new int[256];
image.ProcessPixelRows(accessor =>
{
for (int y = 0; y < accessor.Height; y++)
{
Span<Rgb24> pixelRow = accessor.GetRowSpan(y);
for (int x = 0; x < pixelRow.Length; x++)
{
// Get a reference to the pixel at position x
ref Rgb24 pixel = ref pixelRow[x];
//Fill the histogram arrays with number of appearance of current pixel values (RGB)
red[pixel.R]++;
green[pixel.G]++;
blue[pixel.B]++;
}
}
});
return (red, green, blue);
}
static double CalculateProbability(int j, int[] k) => j / TotalPixelValue(k);
static double TotalPixelValue(int[] i)
{
double totalValue = 0;
for (int k = 0; k < 256; k++)
{
totalValue += i[k];
}
return totalValue;
}
}
/// <summary>
/// The <c>EncryptionClass</c> class.
/// Performs encryption and decryption of a byte array.
/// </summary>
public class EncryptionClass
{
//16 bytes salt
private static readonly byte[] salt = Encoding.Unicode.GetBytes("MySalt");
//iterations for key derivation
private static readonly int iterations = 100_000;
///Encrypt a byte array using Aes block encryption
public static byte[] Encrypt(byte[] plainBytes, string password)
{
byte[] encryptedBytes;
using (Aes aes = Aes.Create())
{
using (Rfc2898DeriveBytes pbkdf2 = new(password, salt, iterations))
{
aes.Padding = PaddingMode.Zeros;
aes.Key = pbkdf2.GetBytes(32); // 256-bit key
aes.IV = pbkdf2.GetBytes(16); // 128-bit IV
}
using (MemoryStream ms = new())
{
using (CryptoStream cs = new(ms, aes.CreateEncryptor(), CryptoStreamMode.Write))
{
cs.Write(plainBytes, 0, plainBytes.Length);
}
encryptedBytes = ms.ToArray();
}
}
return encryptedBytes;
}
///Decrypt a byte array using Aes block encryption
public static byte[] Decrypt(byte[] cryptoBytes, string password)
{
byte[] plainBytes;
using (Aes aes = Aes.Create())
{
using (Rfc2898DeriveBytes pbkdf2 = new(password, salt, iterations))
{
aes.Padding = PaddingMode.Zeros;
aes.Key = pbkdf2.GetBytes(32);
aes.IV = pbkdf2.GetBytes(16);
}
using (MemoryStream ms = new())
{
using (CryptoStream cs = new(ms, aes.CreateDecryptor(), CryptoStreamMode.Write))
{
cs.Write(cryptoBytes, 0, cryptoBytes.Length);
}
plainBytes = ms.ToArray();
}
}
return plainBytes;
}
}