PB à toute heure et à tout moment. (à parcourir avec modération)

Le forum (ô combien francophone) des utilisateurs de Powerbuilder.

Recherche rapide

Annonce

Certaines rubriques, dont des cours, sont uniquement visibles par les membres du forum ^^.
Dans la rubrique Liens & Références, vous avez accès à un sommaire de téléchargement, profitez-en !
Il existe maintenant un nouveau TOPIC "Votre CV en Ligne" accessible uniquement par demande.

#1 19-12-2017 10:48:46

ben147  
Membre Geek
Lieu: Paris
Date d'inscription: 20-06-2008
Messages: 65
Pépites: 293
Banque: 0
Site web

ou exclusif bit à bit

Salut les experts,
bon, je dois calculer un code (un checksum de contrôle, pour être exact) en fonction d'une chaine de caractère, et dans les spec, pour expliquer, il y a un bout de code en C :


s := ‘XX-YYYY-YYYY’;
r := 0;
for i:=1 to 12 do
r := r xor byte(s[i]);
ZZ := intToHex(r,2);


Sauf qu'en PB, xor, j'ai l'impression que ça n'existe pas.
quelqu'un aurait une idée ?
merci !

Dernière modification par ben147 (20-06-2018 08:02:23)

Hors ligne

 

#2 19-12-2017 11:39:56

xlat  
0xc0000005
Award: bf
Lieu: Tanger (طنج)
Date d'inscription: 04-12-2010
Messages: 720
Pépites: 11,343
Banque: 100,221,387,868,884,300
Site web

Re: ou exclusif bit à bit

Hello, bonne question !

Tu peux aller faire un tour sur le site de Seki, rubrique "PbniCW - Cool Wrappers" :

Fonctions logiques pour unsigned longs BitwiseOr(), BitwiseXor(), BitwiseAnd(), BitwiseNot(), BitwiseLeftShift(), BitwiseRightShift()

Sinon le refaire à l'os en pure PB, sachant que le OR et AND et NOT binaire ne sont pas non plus dispo en pb. (pour info

Code:

XOR = (NOT (A AND B)) AND (A OR B)

si je me souviens bien
Mais cela nécessitera de transformer le décimal en binaire avant de faire tes opérations. Sinon peut-être coder une petite DLL qui fait le boulot (non PBNI), je ne crois pas me souvenir qu'il existe une API windows pour ces opérateurs binaires (Bitwise) ni les datawindow expression d'ailleurs.
Une autre solution c'est via le SQL (ici SQL Server supporte nativement AND &, OR |, NOT ~ et XOR ^ :

Code: sql

select a, b, (~ (a & b) & (a | b)) c, a ^ b XOR
from (
select 0 a, 0 b
union select 0, 1
union select 1, 0
union select 1, 1
) as ab

Code:

a  b  c  XOR
------------
0  0  0  0
0  1  1  1
1  0  1  1
1  1  0  0

https://lut.im/eJINqa9o/vAtyxD0h "Don't believe everything you read on the Internet"
    -- Abraham Lincoln

www.ngs.ma

Hors ligne

 

#3 19-12-2017 13:36:17

ben147  
Membre Geek
Lieu: Paris
Date d'inscription: 20-06-2008
Messages: 65
Pépites: 293
Banque: 0
Site web

Re: ou exclusif bit à bit

houlà j'suis un peu largué, là.
bon j'vais relire ta réponse plusieurs fois jusqu'à ce que je comprenne
merci.

Hors ligne

 

#4 19-12-2017 13:57:02

ben147  
Membre Geek
Lieu: Paris
Date d'inscription: 20-06-2008
Messages: 65
Pépites: 293
Banque: 0
Site web

Re: ou exclusif bit à bit

alors je suis allé récupérer la pbl (pbnicw) sur le site de Seki (merci Seki )
je dois ajouter autre chose ? le full build me renvoie des erreurs.

Hors ligne

 

#5 19-12-2017 13:59:04

xlat  
0xc0000005
Award: bf
Lieu: Tanger (طنج)
Date d'inscription: 04-12-2010
Messages: 720
Pépites: 11,343
Banque: 100,221,387,868,884,300
Site web

Re: ou exclusif bit à bit

il te faut surtout le fichier PBX, ensuite tu l'importes dans ton projets ou tu ajoutes la PBD si compatible avec ta version de PB.


https://lut.im/eJINqa9o/vAtyxD0h "Don't believe everything you read on the Internet"
    -- Abraham Lincoln

www.ngs.ma

Hors ligne

 

#6 19-12-2017 18:02:40

buck  
Modérateur
Lieu: Dijon
Date d'inscription: 31-07-2008
Messages: 747
Pépites: 1,028,843
Banque: 171,170,849,654

Re: ou exclusif bit à bit

Bonjour,

Sinon en powerbuilder natif, j'avais eu besoin de cette opération pour piloter les TPE. J'avais extrait les 2 méthodes nécessaires de la PowerBuilder Foundation Class :

Code: pb

long uof_bitwisexor(long al_value1, long al_value2)

//////////////////////////////////////////////////////////////////////////////
//
//  Function:      of_BitwiseXor
//
//  Access:       public
//
//  Arguments:
//  al_Value1    The first value to be used in the operation (e.g. 55).
//  al_Value2    The second value to be used in the operation (e.g. 44).
//
//  Returns:     Long
//            The result of the XOR operation (e.g. 27).
//            If either argument's value is NULL, function returns NULL.
//
//  Description:   Performs a bitwise exclusive OR operation (al_Value1 XOR al_Value2),
//            which exclusively ORs each bit of the values.
//            (55 XOR 44) = 27
//
//////////////////////////////////////////////////////////////////////////////
//
//  Revision History
//
//  Version
//  5.0   Initial version
//
//////////////////////////////////////////////////////////////////////////////
//
/*
 * Open Source PowerBuilder Foundation Class Libraries
 *
 * Copyright (c) 2004-2005, All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted in accordance with the GNU Lesser General
 * Public License Version 2.1, February 1999
 *
 * http://www.gnu.org/copyleft/lesser.html
 *
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals and was originally based on software copyright (c) 
 * 1996-2004 Sybase, Inc. http://www.sybase.com.  For more
 * information on the Open Source PowerBuilder Foundation Class
 * Libraries see http://pfc.codexchange.sybase.com
*/
//
//////////////////////////////////////////////////////////////////////////////

Integer    li_Cnt
Long      ll_Result
Boolean    lb_Value1[32], lb_Value2[32]

// Check for nulls
If IsNull(al_Value1) Or IsNull(al_Value2) Then
  SetNull(ll_Result)
  Return ll_Result
End If

// Get all bits for both values
For li_Cnt = 1 To 32
  lb_Value1[li_Cnt] = uof_getbit(al_Value1, li_Cnt)
  lb_Value2[li_Cnt] = uof_getbit(al_Value2, li_Cnt)
Next

// Perfor the XOR
For li_Cnt = 1 To 32
  If (lb_Value1[li_Cnt] And Not lb_Value2[li_Cnt]) Or &
    (Not lb_Value1[li_Cnt] And lb_Value2[li_Cnt]) Then
    ll_Result = ll_Result + (2^(li_Cnt - 1))
  End If
Next

Return ll_Result

boolean uof_getbit(long al_decimal, unsignedinteger ai_bit) 
//////////////////////////////////////////////////////////////////////////////
//
//  Function:      of_GetBit
//
//  Access:       public
//
//  Arguments:
//  al_decimal    Decimal value whose on/off value needs to be determined (e.g. 47).
//  ai_bit      Position bit from right to left on the Decimal value.
//
//  Returns:     boolean
//            True if the value is On.
//            False if the value is Off.
//            If any argument's value is NULL, function returns NULL.
//
//  Description:   Determines if the nth binary bit of a decimal number is 
//            1 or 0.
//
//////////////////////////////////////////////////////////////////////////////
//
//  Revision History
//
//  Version
//  5.0   Initial version
// 5.0.03  Fixed problem when dealing with large numbers (>32k)
//        from "mod int" to "int mod"
//
//////////////////////////////////////////////////////////////////////////////
//
/*
 * Open Source PowerBuilder Foundation Class Libraries
 *
 * Copyright (c) 2004-2005, All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted in accordance with the GNU Lesser General
 * Public License Version 2.1, February 1999
 *
 * http://www.gnu.org/copyleft/lesser.html
 *
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals and was originally based on software copyright (c) 
 * 1996-2004 Sybase, Inc. http://www.sybase.com.  For more
 * information on the Open Source PowerBuilder Foundation Class
 * Libraries see http://pfc.codexchange.sybase.com
*/
//
//////////////////////////////////////////////////////////////////////////////

Boolean lb_null

//Check parameters
If IsNull(al_decimal) or IsNull(ai_bit) then
  SetNull(lb_null)
  Return lb_null
End If

//Assumption ai_bit is the nth bit counting right to left with
//the leftmost bit being bit one.
//al_decimal is a binary number as a base 10 long.
If Int(Mod(al_decimal / (2 ^(ai_bit - 1)), 2)) > 0 Then
  Return True
End If

Return False

Hors ligne

 

#7 20-12-2017 12:03:27

xlat  
0xc0000005
Award: bf
Lieu: Tanger (طنج)
Date d'inscription: 04-12-2010
Messages: 720
Pépites: 11,343
Banque: 100,221,387,868,884,300
Site web

Re: ou exclusif bit à bit

buck a écrit:

Bonjour,

Sinon en powerbuilder natif, j'avais eu besoin de cette opération pour piloter les TPE. J'avais extrait les 2 méthodes nécessaires de la PowerBuilder Foundation Class :

C'est surement ce qu'il y a de plus simple, après selon le volume de données à traiter par le XOR faut voir.


https://lut.im/eJINqa9o/vAtyxD0h "Don't believe everything you read on the Internet"
    -- Abraham Lincoln

www.ngs.ma

Hors ligne

 

#8 21-12-2017 10:51:44

ben147  
Membre Geek
Lieu: Paris
Date d'inscription: 20-06-2008
Messages: 65
Pépites: 293
Banque: 0
Site web

Re: ou exclusif bit à bit

Alors le truc, c'est que les arguments pour cette fonction, ce sont des long.
or moi, je dois faire ce code, donc :

Code: pascal

s := ‘XX-YYYY-YYYY’; 
r := 0; 
for i:=1 to 12 do 
r := r xor byte(s[i]); 
ZZ := intToHex(r,2);

avec par exemple s = "A0-3ABE-8D94" ......
en gros de l'hexadécimal dans un string.

du coup, euh ... je sais pas ....

j'avais commencé à coder ça, mais ça marche pas, forcément.

Code: pb

ll_r = 0
for i = 1 to 12
  ll_r =bitwisexor(ll_r,  left(right(ls_chaine_remote, 11), i))

next

(et donc c'est le ls_chaine_remote qui est égal à "A0-3ABE-8D94")

Dernière modification par ben147 (21-12-2017 10:54:53)

Hors ligne

 

#9 22-12-2017 11:00:57

xlat  
0xc0000005
Award: bf
Lieu: Tanger (طنج)
Date d'inscription: 04-12-2010
Messages: 720
Pépites: 11,343
Banque: 100,221,387,868,884,300
Site web

Re: ou exclusif bit à bit

Hello, j'avais pas tilté mais ton code c'est pas du C mais du Pascal.
Si tu as un pb suffisement récent utilise blob + getbyte :

Code: pb

string ls_chaine_remote = "A0-3ABE-8D94"
blob lbl_blob
byte lby_byte
long ll_r = 0
int i

lbl_blob = blob( ls_chaine_remote )

for i = 1 to 12
  getByte( lbl_blob, i, ref lby_byte)
  ll_r = uof_bitwisexor(ll_r,  lby_byte)
next

string ls_zz


//ls_zz = to_hex2(r)
//my tohex2:
string ls_alpha = "0123456789ABCDEF"
ls_zz = mid(ls_alpha, 1+ ll_r/16, 1) + mid(ls_alpha, 1 + mod(ll_r,16), 1)

messagebox( "xor ops", "got zz="+ls_zz+" from r="+string(ll_r) )

https://lut.im/eJINqa9o/vAtyxD0h "Don't believe everything you read on the Internet"
    -- Abraham Lincoln

www.ngs.ma

Hors ligne

 

#10 22-12-2017 12:59:02

ben147  
Membre Geek
Lieu: Paris
Date d'inscription: 20-06-2008
Messages: 65
Pépites: 293
Banque: 0
Site web

Re: ou exclusif bit à bit

blob et getbyte ça a l'air de passer, mais au passage de bitwisexor j'ai un bad runtime fonction reference.

bon c'est peut-être parce que j'ai importé la fonction depuis le PBX. je vais essayer en la codant en pb natif, du coup, pour voir.

Hors ligne

 

#11 22-12-2017 13:25:33

ben147  
Membre Geek
Lieu: Paris
Date d'inscription: 20-06-2008
Messages: 65
Pépites: 293
Banque: 0
Site web

Re: ou exclusif bit à bit

bon .... bah les gars .... ça marche.
merci beaucoup, vraiment.
(j'avoue, j'ai pas tout tout compris, ça me stresse un peu, mais bon)

Hors ligne

 

#12 20-06-2018 08:01:19

ben147  
Membre Geek
Lieu: Paris
Date d'inscription: 20-06-2008
Messages: 65
Pépites: 293
Banque: 0
Site web

Re: ou exclusif bit à bit

Bonjour,
je me permet de ré ouvrir ce topic, parce que visiblement, le calcul de mon checksum n'est pas bon .... et je comprend pas pourquoi ....

voici mon code :

Code: pb

lbl_blob = blob( ls_chaine_remote )
for i = 1 to 12
  getByte( lbl_blob, i, ref lby_byte)
  ll_r = uof_bitwisexor(ll_r,  lby_byte)
next
string ls_alpha = "0123456789ABCDEF"
ls_FINREMOTEID = mid(ls_alpha, 1+ ll_r/16, 1) + mid(ls_alpha, 1 + mod(ll_r,16), 1)

avec ls_chaine_remote = "A0-3ABE-8D94"

mon calcul me ramène "6C", et on me dit qu'il devrait ramener "75" ....
et là, je comprend pas .... est-ce que par hasard d'un coup d’œil quelqu'un peut me dire ou est-ce que j'ai foiré ? .....

pour rappel, dans les spec, j'ai ça :

Il s’agit d’un checksum de contrôle basé sur les 12 premiers caractères du REMOTE_ID (tirets compris).
On le calcule en effectuant un « ou exclusif bit-à-bit » sur ces 12 caractères.
La valeur hexadécimale du résultat ainsi obtenu est interprétée comme une chaine de deux caractères également en lettres majuscules.
Exemple :
s := ‘XX-YYYY-YYYY’;
r := 0;
for i:=1 to 12 do
r := r xor byte(s[i]);
ZZ := intToHex(r,2);

Hors ligne

 

Pied de page des forums

Propulsé par FluxBB 1.2.22