Pereiti prie turinio

C, duomenų nuskaitymas ir palyginimas


Rekomenduojami pranešimai

Sveiki,

 

Dirbu su libipq ir vaizdo paketais ir žinau, kad MPEG4 paketai prasideda reikšme 00 00 01 B6. Kaip aš galiu patikrinti ar tikrai dirbu su MPEG4. Kaip aš galėčiau nuskaityti informaciją iš buferio paimtų paketų, kad palyginti turimas reikšmes? Ką reikėtų daryti, jeigu nuskaitoma informacija būtų ne pradžioje paketo, o tarkime 5-8 baitai? Ačiū už bet kokią pagalbą.

 

 case IPQM_PACKET: 
{
// paimu paketus is buferio cia
 ipq_packet_msg_t *m = ipq_get_packet(buf);

  int x;
 if(value in m->payload[x] == value) ??
{
 printf("MPEG packet");
x++;
}

// ir grazinu cia
status = ipq_set_verdict(h, m->packet_id,NF_ACCEPT, 0, NULL); 

 break;
    }

Pilnas kodas: http://pastebin.com/raw.php?i=c2UgZkEj

 

CMD

Redagavo CMD
Nuoroda į pranešimą
Dalintis kituose puslapiuose

 unsigned char ieskomi_duomenys[4]={0x00,0x00,0x01,0xB6};
 int kur_ieskoti=0;
 if(memcmp(&m->payload[kur_ieskoti],ieskomi_duomenys,sizeof(ieskomi_duomenys))==0)
 {
     printf("MPEG packet");
     // ...
 }

 

Dėkui už pagalbą, viskas veikia. Tačiau, ką man daryti jeigu duomenys, kuriuos noriu palyginti yra ne nuo pradžios, o tarkime prasideda nuo 10 baito?

 

kur_ieskoti tiesiog nurodau norimą reikšmę ir tiek?

Redagavo CMD
Nuoroda į pranešimą
Dalintis kituose puslapiuose

Tačiau, ką man daryti jeigu duomenys, kuriuos noriu palyginti yra ne nuo pradžios, o tarkime prasideda nuo 10 baito?

 

kur_ieskoti tiesiog nurodau norimą reikšmę ir tiek?

Taip, jei žinai kur prasideda duomenys. Jei ne, ieškok kaip Silkė sakė.

Nuoroda į pranešimą
Dalintis kituose puslapiuose

Gali pavyzdžiui skippinti per baitus, kol sutiksi NULL, o tada memcmp. Jei nelygu - skippini iki kito NULL :)

 

Ačiū už pagalbą. Dar porą klausimėlių.

Gal galima būtų šiek tiek ant kelio užvesti kaip tas skipinimas per baitus atrodo? Nes nesu su tokiu dalyku susidūręs.

Ir ką daryti tokiu atveju jeigu reikia ieškoti reikšmės 0x00 0x00 0x01 0xb6 00 (01 ar 11) t.y. po jų iškart einančių dviejų bitukų?

Nuoroda į pranešimą
Dalintis kituose puslapiuose

Ačiū už pagalbą. Dar porą klausimėlių.

Gal galima būtų šiek tiek ant kelio užvesti kaip tas skipinimas per baitus atrodo? Nes nesu su tokiu dalyku susidūręs.

Na manau kažkas tokio tavo atveju.

int idx = 0;
while (m->payload[idx] != 0) {
   idx++;
}
// o po šito jau memcmp(). Arba jei su mano minėtu pratęsimu, tai būtų kažkas tokio:
int idx = 0;
while (1) {
   if (m->payload[idx] != 0) {
       idx++;
   }
   else {
       if (memcmp(...) == 0) {
           // turim reikiama vieta, jei gerai suprantu
           break;
       }
   }
}

 

Ir ką daryti tokiu atveju jeigu reikia ieškoti reikšmės 0x00 0x00 0x01 0xb6 00 (01 ar 11) t.y. po jų iškart einančių dviejų bitukų?

Na dėl šito, priklauso kur tie bitukai. Šiaip bet kokiu atveju tiesiog galima pasitelkti bitwise operacijas.

Nuoroda į pranešimą
Dalintis kituose puslapiuose

Tie norimi bitukai eina iškart po ieškomos baitų sekos. Galvoju gal kaip nors įmanoma iškart juos prijungt?

su memcmp bitų nepaieškosi, teks terliotis su bitwise operatoriais :)

 

unsigned char ieskomi_duomenys[]={0x00,0x00,0x01,0xB6};
int idx = 0;
while (1) {
   if (m->payload[idx] != 0) {
       idx++;
   }
   else {
       if (memcmp(&m->payload[idx],ieskomi_duomenys,4) == 0) {
           // sekancio baito pirmieji 2 bitai
           unsigned bitai=m->payload[idx+sizeof(ieskomi_duomenys)]&0x03;


           break;
       }
   }
}

Redagavo rimcx
Nuoroda į pranešimą
Dalintis kituose puslapiuose

su memcmp bitų nepaieškosi, teks terliotis su bitwise operatoriais :)

 

unsigned char ieskomi_duomenys[]={0x00,0x00,0x01,0xB6};
int idx = 0;
while (1) {
   if (m->payload[idx] != 0) {
       idx++;
   }
   else {
       if (memcmp(&m->payload[idx],ieskomi_duomenys,4) == 0) {
           // sekancio baito pirmieji 2 bitai
           unsigned bitai=m->payload[idx+sizeof(ieskomi_duomenys)]&0x03;


           break;
       }
   }
}

 

OK. Jei jau kankintis tai iki galo. Ar aš gerai suprantu, kad unsigned bitai pasimame sekantį baitą einantį po mūsų ieškomų duomenų? idx yra pirmas mūsų ieškomas narys + ieškomas dydis ir atsiduriam kaip tik už ieškomų duomenų.

Tada ANDinam:

x x x x x x x x (0xXX)

0 0 0 0 0 0 1 1 (0x03)

0 0 0 0 0 0 x x gaunam.

 

Ar nereikėtų man ANDint su 0xC0, ko pasekoje gaučiau rezultatą: x x 0 0 0 0 0 0. Ar čia aš blogai kažką suprantu? Ar įmanoma tuos du bitukus per printf kažkaip išvesti į ekraną(kiek ieškojau tai neradau panašaus formato)? Vis dar nepagaunu esmės kaip pasiekiamas palyginimas. Atsiprašau jeigu klausimai skamba nelabai logiškai. Dar kartą ačiū už pagalbą :)

 

Edit: Rytas už vakarą protingesnis, tikiuosi. Jeigu suANDinus su 0xC0 gaunu kažkokį baitą, tai jo du pirmi bitukai liks nepakitę. Tada vėl galiu naudoti memcmp tam poto einančiam baitui ir lyginti su su 0xC0 ar pirmi bitukai 11 arba lyginti su kokiu 0x40 ar 0x80 jei pirmi bitukai 01 ar 10. O paėmus 0x00 galiu patikrinti ar turiu pradžioje 00. Tikiuosi labai nenusišnekėjau.

Redagavo CMD
Nuoroda į pranešimą
Dalintis kituose puslapiuose

OK. Jei jau kankintis tai iki galo. Ar aš gerai suprantu, kad unsigned bitai pasimame sekantį baitą einantį po mūsų ieškomų duomenų? idx yra pirmas mūsų ieškomas narys + ieškomas dydis ir atsiduriam kaip tik už ieškomų duomenų.

Teisingai :)

 

Ar nereikėtų man ANDint su 0xC0, ko pasekoje gaučiau rezultatą: x x 0 0 0 0 0 0. Ar čia aš blogai kažką suprantu?

Čia jau aš blogai supratau; galvojau tau reikia rasti pirmus sekančio baito bitus. Tad tu teisus, reikia ANDinti su 0xC0.

 

Ar įmanoma tuos du bitukus per printf kažkaip išvesti į ekraną(kiek ieškojau tai neradau panašaus formato)? Vis dar nepagaunu esmės kaip pasiekiamas palyginimas. Atsiprašau jeigu klausimai skamba nelabai logiškai. Dar kartą ačiū už pagalbą :)

unsigned char bitai=m->payload[idx+sizeof(ieskomi_duomenys)]&0xC0;
printf("%d\n",bitai>>6); // perstumi tuos 2 bitus per 6 pozicijas i desine ir atspausdini

// XX000000
// >>6
// 000000XX

// arba palygini if( (bitai >>6)==3) ar pan.

 

Edit: Rytas už vakarą protingesnis, tikiuosi. Jeigu suANDinus su 0xC0 gaunu kažkokį baitą, tai jo du pirmi bitukai liks nepakitę. Tada vėl galiu naudoti memcmp tam poto einančiam baitui ir lyginti su su 0xC0 ar pirmi bitukai 11 arba lyginti su kokiu 0x40 ar 0x80 jei pirmi bitukai 01 ar 10. O paėmus 0x00 galiu patikrinti ar turiu pradžioje 00. Tikiuosi labai nenusišnekėjau.

Nereik jokio memcmp jei tau reikia palyginti tik 1 baitą ar bitus, tiesiog palygini su if ir AND

if(bitai&0x80){} //tikrini pirmąjį bitą, t.y. X0000000
if(bitai&0x40){} //tikrini antrąjį bitą, t.y  0X000000
if(bitai==0){} // tikrini ar abu bitai lygus 0, kiti bitai bet kokiu atveju bus lygus 0 po AND 0xC0 operacijos

arba if( (bitai >>6)==3) ar pan.

Nuoroda į pranešimą
Dalintis kituose puslapiuose
  • po 3 savaičių...
  • po 2 savaičių...

Ačiū rimcx dar kartą. Viskas veikia puikiai.

 

Dar vienas klausimėlis, kad nekurti atskiros temos. Ar tokiu būdu bus N-tasis narys keičiamas baitu 0xFF mūsų pakete, kuriame rasta ieškoma baitų seka?

 

unsigned char data[4]={0x00,0x00,0x01,0xb3};
int k = 0;
int j;
int N = 25;
while(k < m->data_len) {


   if (m->payload[k] != 0x00) {
       k++;
   			       }
   else {
   if (memcmp(&m->payload[k],data,sizeof(data))==0) {
if(j % N == 0) { 

m->payload[j]=0xff;

              }
    else {break;}  	                              } 
else {
k++;   }
j++;	 }
	      }

 

EDIT3: Problema išspręsta.

Redagavo CMD
Nuoroda į pranešimą
Dalintis kituose puslapiuose

Prisijunkite prie diskusijos

Jūs galite rašyti dabar, o registruotis vėliau. Jeigu turite paskyrą, prisijunkite dabar, kad rašytumėte iš savo paskyros.

Svečias
Parašykite atsakymą...

×   Įdėta kaip raiškusis tekstas.   Atkurti formatavimą

  Only 75 emoji are allowed.

×   Nuorodos turinys įdėtas automatiškai.   Rodyti kaip įprastą nuorodą

×   Jūsų anksčiau įrašytas turinys buvo atkurtas.   Išvalyti redaktorių

×   You cannot paste images directly. Upload or insert images from URL.

Įkraunama...
  • Dabar naršo   0 narių

    Nei vienas registruotas narys šiuo metu nežiūri šio puslapio.

  • Prisijunk prie bendruomenės dabar!

    Uždarbis.lt nariai domisi verslo, IT ir asmeninio tobulėjimo temomis, kartu sprendžia problemas, dalinasi žiniomis ir idėjomis, sutinka būsimus verslo partnerius ir dalyvauja gyvuose susitikimuose.

    Užsiregistruok dabar ir galėsi:

    ✔️ Dalyvauti diskusijose;

    ✔️ Kurti naujas temas;

    ✔️ Rašyti atsakymus;

    ✔️ Vertinti kitų žmonių pranešimus;

    ✔️ Susisiekti su bet kuriuo nariu asmeniškai;

    ✔️ Naudotis tamsia dizaino versija;

    ir dar daugiau.

    Registracija trunka ~30 sek. ir yra visiškai nemokama.

  • Naujausios temos

  • Karštos temos

×
×
  • Sukurti naują...