Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Operatory bitowe PHP/C
Forum PHP.pl > Forum > PHP > Pro > Archiwum Pro
scanner
Ludzie, ja wiem, że jest poźno, ale zacznijcie czytać tego manuala. Ciągniecie wątek pisząc coś, co nie jest prawdą.

Od kiedy w php znak "^" to potega? Według mnie i manuala:
Cytat
Operatory bitowe służą do operowania na wartościach konkretnych bitów w liczbie. Jeśli zarówno lewo jak i prawostronne operandy są typu string, operatory bitowe będą wykonywać operacje na poszczególnych znakach tych łańcuchów.  


$a ^ $b
Sumowanie bitowe modulo 2
Dany bit wynikowy jest równy 1 wtedy i tylko wtedy, kiedy jeden z bitów składowych jest równy 1 a drugi jest równy 0.

A jeśłi mnie moja przemęczona głowa nie myli to:
[php:1:d06f1d6bf9]<?php
$a = $a ^ $b
// jest równoznaczne z
$a ^= $b
?>[/php:1:d06f1d6bf9]

Przypominam także o: [php:1:d06f1d6bf9]<?php echo sprintf("Dwójkowo: %b", 123); ?>[/php:1:d06f1d6bf9]
scanner
Cytat
To wytłumacz jeszcze (...)

Kod
Bitowo:



00000001 ^ 00000001 = 00000000

10101010 ^ 10101010 = 00000000

10101010 ^ 01010101 = 11111111

00011000 ^ 00110011 = 00100011
Już jasne ?
5z474n
co w C++ znaczy:
Kod
b = (a >> 24) | (a << 8);

i
Kod
va_list ap;

va_start(ap, format);

va_arg(ap, unsigned char*)



:cry:
mateuszkrzeszowiec
Opłaca się studiować informatykę: smile.gif

ptaszek to XOR

Jak nie wiecie co to XOR to tu przykład

1 XOR 1 =0
1 XOR 0 =1
0 XOR 1 = 1
0 XOR 0 = 0

Czyli jeżeli mamy dwa różne bity to XOR na nich daje 1, jeżeli są równe daje zero.

Bardziej "rozbudowane":
11110000111100000000 XOR 00001111000011110000 = 11111111111111110000
mateuszkrzeszowiec
operatory >> oraz << służą do przesunięcia bitów w prawo/lewo.

Na przykład 10>>1=1
1<<1=10
1<<4=10000
Operator | oznacza bitowe or czyli bitowe dodawanie
Bitowe dodawanie to coś takiego co daje wynik zero jeśli obydwa bity są równe zero, w każdym innym wypadku daje jeden

Na przykład 110000 | 000001 = 110001

P.S.
Była omyłka smile.gif
mateuszkrzeszowiec
Na takie pytania wyrwane z kontekstu ciężko się odpowiada

Wyrażenie :
Kod
b = (a >> 24) | (a << 8);

Robi po kolei
Przesuwa bitowo wartość zmiennej a w prawo o 24 miejsca, przesuwa bitowo wartość zmiennej a w lewo a następnie sumuje otrzymane liczby bitowo i przypisuje wynik zmiennej b. smile.gif

Cytat
va_list structure Used to hold information needed by va_arg and va_end macros. Called function declares variable of type va_list that can be passed as argument to another function.  


P.S.
Ale wpadka smile.gif
Jabol
ze względu na sporą niewiedzę ludzi na forum o operatorach bitowych postanowiłem przykleić go na pewien czas (dokładnie do dzisiaj wieczorem). Teraz jeszcze tylko dodatek o innych operatorach bitowych:

| -sumowanie bitowe
0 | 0 = 0
0 | 1 = 1
1 | 1 = 1

& -mnożenie bitowe
0 & 0 = 0
0 & 1 = 0
1 & 1 = 1

negacja bitowa
~ 0 = 1
~ 1 = 0
5z474n
Kod
int gg_http_hash(const char *format, ...)

{

    unsigned int a, c;

    va_list ap;

    int b = -1, i, j;



    va_start(ap, format);



    if (!format)

  return 0;

    

    for (j = 0; j < strlen(format); j++) {

  unsigned char *arg, buf[16];



  if (format[j] == 'u') {

     snprintf(buf, sizeof(buf), "%d", va_arg(ap, uin_t));

     arg = buf;

  } else {

     if (!(arg = va_arg(ap, unsigned char*)))

    arg = "";

  }    



  i = 0;

  while ((c = (int) arg[i++]) != 0) {

     a = (c ^ b) + (c << 8);

     b = (a >> 24) | (a << 8);

  }

    }



    return (b < 0 ? -b : b);

}


prosze oto calosc smile.gif
mateuszkrzeszowiec
O boże a po co ci to? smile.gif
Jabol
Cytat
1<<4=1000
chyba
1<<4=10000, jedno zero w tą czy w tą, ale zawsze sie liczy
5z474n
zeby obliczyc hash dla adresu e-mail, hasla przy rejestrowaniu nowych nr gg a mam ta funkcje tylko w C++ i nei moge sobie poradzic z przelozeniem tego na php :mrgreen: bo wogole nie kumam C++ jest to moj pierwszy kontakt z tym jezykiem :]
mateuszkrzeszowiec
No dobra...

Ostrzegam, jestem początkującym programistą i to może być wielka pomyłka smile.gif
Proszę się nie śmiać jak ktoś zna C++, jestem jeszcze młodym studentem informatyki smile.gif



[php:1:a7884bbe73]int gg_http_hash(const char *format, ...) //deklaracja funkcji, pierwszy parametr to wskaźnik do stringa, funkcja może mieć opcjonalne parametry
{
unsigned int a, c;
va_list ap;
int b = -1, i, j;

va_start(ap, format); //"przechwytujemy" dodatkowe (opcjonalne) parametry funkcji

if (!format) //jeśli parametr format jest stringiem pustym (a w zasadzie to wskaznikiem na NULL albo zerem ('') funkcja zwraca zero i kończy działanie
return 0;

//jeśli są parametry robimy z nimi różne śmieszne rzeczy.
//poniżej (kawałkami tylko napiszę
//wykonujemy tyle razy jaką długość miał format, deklarujemy wskażnik do stringa i stringa (lub jak kto woli: tablicę znaków)
for (j = 0; j < strlen(format); j++) {
unsigned char *arg, buf[16];
//jeżeli aktualny znak(pod tym indeksem w stringu, bo string to nic innego jak tablica znaków) stringa format jest równy 'u' to:
if (format[j] == 'u') {
// do buf wstawiamy znaki zakończone znakiem końca stringa, liczbę znaków którą opisuje liczba sizeof(buf) (czyli 16*8 bitów), następnie jest formatowanie, po kolejnym przecinku jest źródło czyli pobieramy kolejny przekazany opcjonalny parametr smile.gif
snprintf(buf, sizeof(buf), "%d", va_arg(ap, uin_t));
// w arg zapisujemy to cośmy przed chwilą dostali
arg = buf;
} else {
//jeżeli aktualny argument nie jest znakiem 0 (czyli "") to w arg zapisujemy nic (czyli ""), jeżeli nie był pusty to zostawiamy go
if (!(arg = va_arg(ap, unsigned char*)))
arg = "";
}

i = 0;
//zczytujemy sobie po kolei (po znaku) z arg znaki i robimy z nimi bitowe szaleństwa smile.gif
while ((c = (int) arg[i++]) != 0) {
a = (c ^ cool.gif + (c << 8);
b = (a >> 24) | (a << 8);
}
}
//jeżeli po tym wszytkim b < od zera to zamieniamy je na dodatnie, jeżeli dodatnie to zwracamy je
return (b < 0 ? -b : cool.gif;
}[/php:1:a7884bbe73]
mateuszkrzeszowiec
Po ludzku, dostajemy do funkcji nieznaną ilość parametrów, znamy tylko (nie jestem pewnien) ilość tych parametrów.

Następnie je zasysamy, po 16(długość buf)*8(długość typu char) bitów, i przemielamy za pomocą różnych operatorów logicznych, jeśli dla aktualnego parametru (tu: miejsce w pamięci) znak w stringu format ma wartość 'u'.
5z474n
dzieki! dzieki! ... a teraz zobaczymy co z tym zrobic :]

zapomnialem dodac ze

format... - format kolejnych parametrów ('s' jesli dany parametr jest
ciagiem znaków lub 'u' jesli numerem GG)

ale i tak jest dobzre smile.gif
zrob z tego [ php ] a nei [ code ] to bedzie wyrazniej smile.gif dzieki
mateuszkrzeszowiec
Matko święta, naprawdę ci pomogłem?questionmark.gif

Dziwne, bo jeszcze nie miałem c++ (jestem dopiero na drugim semestrze smile.gif )
5z474n
pomogles ... wczesniej wogole ne iwiedzialem co z tym zrobic smile.gif i co wiekszosc z tych znczkow oznacza smile.gif
spenalzo
Cytat
Operatory bitowe służą do operowania na wartościach konkretnych bitów w liczbie.

Sorry za lamerstwo: ale do czego to służy?! Tzn. jakie są konkretne zastosowania tego "czegoś"?
mateuszkrzeszowiec
Cytat
zeby obliczyc hash dla adresu e-mail, hasla przy rejestrowaniu nowych nr gg


Za przeproszeniem czytać nie umiesz? smile.gif

Generalnie chodzi o to że musisz wydobyć jakieś dane a są one znakowo, a ty potrzebujesz konkretnych bitów.

W php to się raczej rzadko przydaje, ale w C, C++ często. Na przykład do obsługi ekranu. Bo tam ustawiasz konkretny bit, a nie np: cały znak (czyli 255 dziesiętnie, FF szesnastkowo, dwójkowo 11111111)

Np: żeby zapisać 4 "opcje" np":
ma kółko/nie ma
ma kierownice/nie ma
ma dach/nie ma
ma siedzenia/nie ma
normalnie potrzebujesz czterech zmiennych.

Ale da się to zrobić jedną zmienną. Po prostu:
0 to niczego nie ma
1 ma kółko, nie ma reszty
2 ma kierownice, nie ma reszty
3 ma kółko, ma kierownice, nie ma reszty
itd.

Ale łatwiej zapisać (wg mnie i innych też smile.gif )
0000 nie ma nic
0001 ma kółko
1001 ma kółko i siedzenia.

jak wyzerować coś? Konkretne miejsce? a prosto, potrzebujesz jedynie "wzorców", a wygląda to tak:

masz ustawione
ustawienia=0000
chcesz żeby były siedzenia, robisz tak:
siedzenia=1000;
nowe=siedzenia|ustawienia;
co więcej: to wyrażenie nie zmieni wartości pozostałych bitów, po prostu masz pewność że na najstarszym bicie będziesz miał 1.

A jak coś sprawdzić? Pomyśl, idę już spać, jak chcesz to dopiszę jutro jeszcze trochę smile.gif
spenalzo
Cytat
Za przeproszeniem czytać nie umiesz? smile.gif

Chodziło mi, żeby ktoś to opisał dokładnie w taki sposób (na prostym przykładzie) jak Ty to zrobiłeś.

Cytat
W php to się raczej rzadko przydaje, ale w C, C++ często.

Teraz widzę że raczej tak :-)

Cytat
Ale łatwiej zapisać (wg mnie i innych też smile.gif )
0000 nie ma nic
0001 ma kółko
1001 ma kółko i siedzenia.

Ale wydaje mi się że w php raczej nie jest konieczne czy potrzebne stosowanie czegoś takiego.

Cytat
A jak coś sprawdzić? Pomyśl, idę już spać, jak chcesz to dopiszę jutro jeszcze trochę smile.gif

Może operator &? Nie śmiejcie się proszę!
A wyjaśniania starczy. Już wiem (mniej więcej) o co chodzi. Mam teraz ogólne pojęcie o tym, ale i tak magia, dzięki za wyjaśnienia.
Przydałaby się teraz opcja drukowania.
mateuszkrzeszowiec
Co do tego że w php niepotrzebne to nie tak do końca, bo np jeżeli robisz duży projekt a masz ograniczenie pamięci do jakiejśtam wartości to użycie tego sposobu zapisu daje znaczne oszczędności. Ale to musiałby być naprawdę duży projekt.

Dodam, że typ int ma 32 bity, czyli daje możliwość zapisania 32 "opcji". Gdyby zapisywać każdą opcję w osobnej zmiennej typu int to zajętość pamięci = 32*32= 1024 bity czyli 128 bajtów, natomiast w jednej zmiennej byłyby to tylko 4 bajty. Różnica jest i to znaczna smile.gif

P.S.
Jeżeli chcesz/chcecie to przybliże tą tematykę jeszcze dokładniej smile.gif

P.P.S.
Pozatem zmiana (wyłączenie wszystkich, włączenie wszystkich itd) takich 32 opcji jeśli są zapisane w 32 zmiennych wymaga 32 przypisań, jeżeli w jednej zmiennej dwójkowo to jest potrzebne tylko jedno przypisanie!
spenalzo
Cytat
Jeżeli chcesz/chcecie to przybliże tą tematykę jeszcze dokładniej smile.gif

Jeżeli chcesz to jak najbardziej. Zaciekawiło mnie to :-)
5z474n
ja sie poddaje ..... myslalem ze fartem sie to uda pzrerobic :| ale sie pzreliczylem :cry: ............. nawet ne iwiem arg jest tablica ? czy ciagiem znakow :| i co ta funkcja wogole robi :| c jest z ty m u :| rh.... trzeba do tego inaczej podejsc .......... moze kiedys .... :mrgreen:


a moze zrobie calosc w c++ bo w druga strone ( czyli funkcje php raczej sa w c++ ) sie powinno udac 8O tylk ojak odpalic cos co jest w c++ na komputerze 8O oto jest pytanie !
mateuszkrzeszowiec
Żeby to wszystko zaczęło działać potrzebna jest mała pomoc z "zewnątrz".

W następnym poście będzie funkcja w C i jej wersja php, 5z474n zasłał mi ją maliom, nie wiem czy będzie działać, sprawdzę jak DOSTANĘ WRESZCIE PARAMETRY JEJ WYWOŁANIA A NIE TYLKO NAZWY ZMIENNYCH!
5z474n chodzi mi o to żebyś dał mi konkretne dane jakie funkcja otrzymuje, to sprawdzę wynik w C i w php i porównam smile.gif


Co robi? Domyślcie się smile.gif
Chodzi o to że traktuje php'powego int jakby był 32 bitowym intem bez znaku.
[php:1:b04efc8b5b]<?php
//pierwszy parametr musi byc liczba int, nieujemna!!!!!
//drugi parametr to przesunięcie, rowniez int ale moze byc ze znakiem
//1 to o jeden bit w lewo
//-1 to o jeden bit w prawo
//UWAGA!!! NIE MA TESTU POPRAWNOSCI DANYCH!!!
//JAK WYWOLANIE BEDZIE ZLE TO WYJDA BZDURY!!!
function byte_shift($number, $how)
{

//konwersja na dwojkowy
for($i=0;$i<32;$i++)
{
$tab[$i]=$number%2;
$number=($number-$tab[$i])/2;
}
$number=0;


while($how!=0)
{
//przesuwamy w lewo
if($how>0)
{
$buffer=$tab[31];
for($i=30;$i>-1;$i--)
{
$tab[$i+1]=$tab[$i];
}
$tab[0]=$buffer;
$how--;
}
//a tu w prawo
else
{
$buffer=$tab[0];
for($i=1;$i<32;$i++)
{
$tab[$i-1]=$tab[$i];
}
$tab[31]=$buffer;
$how++;
}
}


//konwersja na dziesietny
for($i=0;$i<32;$i++)
{
$number=$number+pow(2,$i)*$tab[$i];
}
return $number;
}
//przykładowe wywołanie
echo(byte_shift(2,2));
//efekt=8
?>[/php:1:b04efc8b5b]
mateuszkrzeszowiec
Wersja C
[php:1:009f5a8e85]<?php
int gg_login_hash(char *password, int seed)
{
unsigned int x, y, z;

y = seed;

for (x = 0; *password; password++) {
x = (x & 0xffffff00) | *password;
y ^= x;
y += x;
x <<= 8;
y ^= x;
x <<= 8;
y -= x;
x <<= 8;
y ^= x;

z = y & 0x1f;
y = (y << z) | (y >> (32 - z));
}

return y;
?>[/php:1:009f5a8e85]

Wersja php
[php:1:009f5a8e85]<?php
function gg_login_hash($password, $seed)
{
$y=$seed;

for($i=0;$i<strlen($password);$i++)
{
$x = ($x & 0xffffff00) | ord($password[$i]);
$y^=$x;
$y+=$x;
$x=byte_shift($x,8);
$y-=$x;
$x=byte_shift($x,8);
$y^=$x;
$z=$y & 0x1f;
$y=byte_shift($y,$z) | byte_shift($y,32-$z);
}
return $y;
}?>
[/php:1:009f5a8e85]

Działa, zwraca to samo co funkcja w C !!!

Dla dociekliwych:
Wynik może być ujemny, i nie jest to błąd.
Czy jest to istotne czy nie, zależy od "reszty" programu. W C możemy sobie dowolnie zrzutować (albo na signed albo unsigned) i nie ma problemu. W php to niemożliwe, musimy wykorzystać wynik jako zwykłego int'a. Ale myślę że wiem co poeta chciał powiedzieć. Skoro funkcja w C ma zwracać zwykłego int'a to raczej "na zewnątrz" taka wartość właśnie jest używana.

P.S.
spenalzo, jeszcze odrobina cierpliwości smile.gif, jutro mam kolosa...
P.P.S
Jeśli zajdzie potrzeba zmiany też pierwszej funkcji (tej bardziej skomplikowanej) to też napiszę, powiedzcie tylko że chcecie, bo dla próżnicy to mi się robić nie chce smile.gif.
5z474n
w krotce moze powiem co dokladnie sie pzrekazuje do tej funkcji ... smile.gif

Cytat
hash liczony z pól email i pwd.

email to e-mail a pwd to hasl onowego numeru


Cytat
Przykład:  

POST /appsvc/fmregister2.asp HTTP/1.0
Host: register.gadu-gadu.pl
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/4.0 (compatible; MSIE 5.0; Windows 98)
Content-Length: 62
Pragma: no-cache
 
pwd=sekret&email=moj*adres!email.pl&qa=5~Maria&code=1104465363Jeśli wszystko przebiegło poprawnie, serwer odpowie:  

reg_success:UIN

Gdzie UIN to nowy numer, który właśnie otrzymaliśmy.



NIe wiem dlaczego moj*adres!email.pl jest tak dziwnei napisne :|
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.