İkilik bir veriyi 64 bitlik parçalara bölmek

Elimde string olarak saklanan ikilik bir veri dizisi var. Bu veri dizisi 64 bitin katları genişliğinde olma ihtimali var .(64, 128, 192…) Ben bu ikilik veriyi 64 bit 64 bit olacak şekilde nasıl bölebilirim? İki ana mesele var:

  1. Verinin uzunluğu belli değil ama uzunluğu 64 bit ya da 64’bitin katları…
  2. Verinin bir liste içinde saklanmasını istiyorum. Örneğin veri 128 bitse iki elemanlı bir liste olacak.

Bunu nasıl yapabilirim?

len()

Python string length | len() - GeeksforGeeks

Python Examples of bitstring.Bits (programcreek.com)

How do I determine the size of an object in Python? - Stack Overflow

64 yerine 3 olsun her alt-string’in boyutu, toplamda da mesela 15 karakter olsun:

101 110 001 001 000
^^^ ^^^ ^^^ ^^^ ^^^

Bir döngü gerekiyor: her döndüğünde 3 adet alsın ve ilerlesin. while da olur, for da olur, list comprehension ile de yapılabilir. Siz neler denediniz?

1 Beğeni

Anlamadım bir örnek yapar mısınız?

15 karakter 15*8 = 90 bit yapar.

3 bitlik verilere neden ayırıyoruz. neden 3 er bitlik 5 tane?

Bir bilgisayar 2 nin katlarına göre neden veri alır?

Bunun verinin boyutunu belirleyip, 64 bitlik bloklara ayrılması ile ne alakası var anlamadım.

Gerçekten şu döngü gerektiren, 3 er adet alıp ileten, for da olan list comprehension da olan kodunuzu merak ettim. Ekler misiniz buraya.

Ellerindeki string’in "101110001001000" formunda olduğunu zannediyorum, ona göre yazmıştım.

s = "101110001001000"
adim = 3
print([s[i: i+adim] for i in range(0, len(s), adim)])

Elinde girdiği verinin boyu değişken,

s = “101110001001000”

neden seçtin? Ve neden 15 bit? Sanki 64 bitten büyük değişken bir bit dizisinden bahsediliyor?

Bir de neden print ettin?

64 bitlik parçalara ayırmak istiyorum demiş, verdiğin kod 64 bitten büyük herhangi bir verinin 64 bitlik parçalara ayrılmasını mı sağlıyor?

Yani sorudaki ile senin anlattığını hala ilintileyemedim.

Biraz daha açıklamak istermisin?

Bana soru şu gibi geldi

X bir bit dizisinin boyutunu belirten tam sayı.

X>64 ve biz bu X adet bitten oluşan bit dizisini,

64 bit lik parçalara ayırıyoruz.

Ve bunu nasıl yaparız gibi bir soru sanki?

Sence yukarıdaki kod buna cevap veriyor mu?

Yapılan işlemi örneklendirmek adına.

Ne yaptığı ekranda görülsün diye.

s orada girdiyi temsil ediyor, adim’a da 64 yazarsanız o işi yapıyor. "O iş"ten kastım da şu:

Olabilir, yok, belki. En iyisi soruyu soran kişinin yanıt vermesi gibi; yanlış anladıysam bunu belirtebilir veya yanıtı görmezden gelebilir, çok önemli değil.

2 Beğeni

Benim için problem olan şey bu bölünmüş verilerin nasıl depolanacağı. Bir liste içinde string olarak tutmak istiyorum. Döngüyü nasıl kuracağımı kestiremedim doğrusu.

Şu şekilde problemi çözdüm:
Not: ascii2binary fonksiyonu 64 bit ya da katları uzunluğunda ki string olarak depolanan binary veriyi döndürür.

bin = self.ascii2binary("Merhaba Yazbel")


# splitting into 64-bit chunks
length = len(bin) // 64 # number of list length
bin_list = [None] * length
list_index = 0
data = ""

_from = 0
_to = 64
while list_index != length:
    for i in bin[_from:_to]:
        data += i
    bin_list[list_index] = data
    
    data = ""
    _from += 64
    _to += 64
    list_index += 1
print(bin_list)

@anon18277073 'in tek satirlik fonksiyonu da calisiyor:

def ascii2binary(asc):
    return ''.join([f"{c:08b}" for c in asc.encode('ascii')])

bin_ = ascii2binary("Merhaba Yazbel")
print("  " + bin_)

def splitbinary(bin_, adim):
    return [bin_[i: i+adim] for i in range(0, adim * (len(bin_) // adim), adim)]

print(splitbinary(bin_, 64))
1 Beğeni

Çok temiz bir çözüm olmuş. Teşekkür ederim @anon18277073 @aib .
Ancak şu kısmı anlayamadım açıklar mısınız?

bin_[i: i+adim]
for i in range(0, adim * (len(bin_) // adim), adim)

Yukarıdaki kod parçacığında range() fonksiyonu ile i değeri sırasıyla 0, 64, 128 şeklinde ilerliyor yani 64’ün katlarına göre.

Döngü içerisinde ise her iterasyonda liste içerisine bin_[i: i+adim] şeklinde bir liste ekleniyor. i değerine bakacak olursak sırasıyla bin_[0: 64], bin_[64: 128] şeklinde bin_ değişkenini 64’lük uzunluklara bölüyoruz ve tüm bunları bir liste içerisinde return ediyoruz.

2 Beğeni

Her çözüm çözümdür.

Nereye takıldığımı anlamanızı bekliyorum…

Python Split String into Specific Length Chunks - Python Examples

Yazar geçerdim.

Ama özellikle belli adımları yakalamanı istiyorum.

Bu açtığın başlıklardan bir kaçına bakarsak,

Bir kripto algoritması üzerinde çalışıyorsun.

Kripto algoritması için hakim olmanı istediğim hususlar var.

Yoksa dediğim gibi direkt üstteki linki yapıştırırdım, diğer katılımcıların düştüğü gibi binary çevirme konusuna yeniden gelmen gerekirdi.

Bu nedenle işlemlerini binary olarak yürütmeni tavsiye ediyorum.

Karakter dizisini aldıktan sonra tüm işlemlerini hep binary yürüt.

len() ile çalışırken binary üzerinde çalış.

Yada kendi nesnelerini uzunlukarını takip edebil diye ilk mesajdaki linkleri verdim.

Bu sayede şu noktalara bakmanı sağlayacaktım…

Ve nacizene bir kaç tavsiyem olacaktı.

Mesela bölme operatörü (/), modül operatörü (%)

gibi.

Ardından şunu söylemeyi düşünüyordum…

Mümkün olduğunca hazır kütüphaneleri kullan, iki nedenle, birincisi belirli kurallara göre yazıldıkları için kullanımı kolaydır, ikincisi esnek ve hızlı çalışmaları için optimize edilmişlerdir.

Özellikle bir de örnek verecektim.

NumPy Splitting Array (w3schools.com)

np.array_split () ile zaten dizilerini, iki boyutlu dahil rahatlıkla parçalara bölebilirsin.

divmod(len(arr), 64) olarak bakıp.

bolen+kalan toplamına bolerek hızlıca dizilerini bölünmüş hale getirebilirsin.

döngü falan da gerektirmez.

arrdivide = np.array_split (arr, bolum+1 (kalan varsa))

Gibi bir satırda böler geçersin.

arrdivide[0] da birinci dizi,
arrdivide[1] de ikinci dizin şeklinde gider.

Bunlar liste bölme kısmı.

Ama bit bazında çalışırsan daha hızlı olacaktı.

Sonrasında aslında bu işlerin böyle yapılmadığı,
<< ve >> operatörleriyle 64 bit kaydırarak rahatlıkla yapılabileceğini gösterecektim.

Genelde kriptolojide bit kaydırarak verileri almak ve daha önce bildiğim üzere bu kodu, 64 bitten uzun verileri kırpıp xorlamak için kullanacağını bildiğim için bu konuda örnekler vermek istiyordum.

Orada da çekincelerim var aslında.

Xor yetersiz gibi, bir de 64 bite kırpıp xorlarsan farklı uzunluktaki anahtarlar aynı anahtara dönüşebilir ve bu bir zaafiyete neden olabilir.

Bunların alt yapısını oluşturmak adına ön bilgi oluşturmadan tam kod vermiyorum özellikle.

Tabi yazdıklarımın ne kadarını anlatabildim bilmiyorum.

Buradan özetle.

  1. Bit düzeyinde çalış.

  2. Dizi bölmek için kütüphane kullan.

  3. Kütüğhane kullanmayacaksan en azından bit düzeyinde shift operatörleri ile veriyi kaydırarak kullan.

  4. Son olarak en önemlisi elde ettiğin dizileri xorlamak yerine biraz daha düşünelim ve anahtarları kısaltmak için daha makul bir çözüm araştıralım.

4 Beğeni

Bütün kodlar çalışır.

Kodu string alıp string döndürüyor.

Sizin yaptığınız gibi {:08b} ile formatlanmış ve ascii yi binary ye çeviren bir fonksiyonu yok.

Zaten sorum tam da buydu.

Örneği de şundan irdeledim 3 er bölüp 15 vermiş.

Tam bölünmeyen bir veri üzerinde son veriyi nasıl hizalarız yada hizalamalıyız onu merak ettim…

16 bit olsa mesela son dizi 1 elemanlı olacak.

Bunun üzerinde durmak istedim.

2 Beğeni

64 bitin katlarını tamamlamak için kalan boşluk sayısı karakterini dolduruyorum. ascii2binary fonksiyonunun içine gömülü.

semtex** → semtex22
aib***** → aib55555

Bahsettiğin hususlar gerçekten çok önemli. Dediğin gibi xor güvenlik açığı oluşturabilir ama çok düşük bir ihtimal olduğunu varsaydığından ötürü pek üzerine düşmemiştim.

Amacım yapmaya çalıştığım algoritmayı kullanmak değil. Modern Kriptografiyi anlamak ve Python becerilerimi geliştirmek için algoritmayı taklit etmeye çalışıyorum.

Bit düzeyinde çalışmak siz söylemeden önce aklıma gelmişti. Ama verinin kapladığı alan aynı olduğundan ötürü değiştirmeye yeltenmedim. (64 bit)

1 Beğeni

Tabi ki böyle yapabilrsin.

Ama benim bir kaç nacizane tavsiyem olacaktı.

  1. Öncelikle diziyi ikili bir dizi haline getir.

  2. divmod( ) fonksiyonu ile aldığın dizinin 64 ün kaç katı ve son dizi boyunun kalanlı kısmı bilgisini ald.

Diziyi sanal olarak bölsen yeter. Tamamen bölmeni gerektiren bir durum yok.

Dizinin, 0-63, elemanlarını 64,127 elemanları ile xorla, 128, n elemanıyla tekrar xorla.

Aslında fiilen diziyi bölmen gerekmiyor.

  1. Boşlukları bir değer ile doldurursan, tekrarlayan bir anahtarla açığa sebep olabilirsin.

  2. Kodunu mutlaka binary sürdür. İşlemlerini binary olarak yap. 1 bit tutmak için 1 byte harcatacak şekilde tutma.

Aslında sana şunu önerecektim.

RC5 Encryption Algorithm - GeeksforGeeks

Ama sanırım DES çalışmaya çalışıyorsun.

Ve daha da önemlisi, anahtarını belirli bir yerde sınırlamak zorunda değilsin. Şifreleyeceğin blok üzerinde anahtarı gezdirerek istediğin uzunlukta anahtarla şifreleyebilirsin.

Her biri ayrı tartışma konusu. Bazı kararları kafanda şekillendirdiğin için o kısımlara girmedim.

Konu uzun sayfalarca örnek yazabiliriz.

Her çözümün artıları ve eksileri var.

Mesela ufuk açması açısından.

Böldün, xorladın, boşlukları da hizalamak için bir veriye dönüştürdün.

Peki anahtarın asıl halini geri oluşturabilecek misin?

Can alıcı öneri, aslında sana önceki başlığında çarp böl topla derken, anahtarını da şifrele demek istemiştim.

Hem boyutunu kontrol edebilirsin hem de anahtarını kriptolu halinden geri oluşturabilirsin.

Bir düşün istersen.

3 Beğeni

GitHub - boppreh/aes: A pure Python implementation of AES, with optional CBC, PCBC, CFB, OFB and CTR cipher modes.

A pure python implementation of the DES and TRIPLE DES encryption algorithms · GitHub

Gibi kodların üzerinden çalışmayı da tercih edebilirsin.

3 Beğeni