8
votes

Comment combiner deux valeurs de gestion

Je tiens à combiner deux valeurs de gestion et à générer une valeur alphanumérique 32 bits (elle peut être effectuée à l'aide de hachage).


6 commentaires

Quel est le but ou raison de faire cela?


Pourquoi avez-vous besoin de "combiner" deux guidons?


J'ai deux valeurs d'entrée Gudi à partir de ces deux valeurs que je veux générer une valeur GUI unique, qui peut être une valeur alphanumérique de 16 bits ou 32 bits.Ce est utilisé pour générer une URL pour l'utilisateur, conformément à mon client.


Mais peu importe la façon dont vous "combiner" deux guidons, il n'y a plus de garantie d'unicité - sauf si vous ne les ficitez pas ensemble guid1.tostring () + guida2.tostring ()


La solution de Paul est ce que vous recherchez. Il hachait 2 matrices d'octets GUID ensemble. (Un GUID est une matrice de 16 octets, pas de 16 bits comme votre question) Le résultat est un nouveau GUID qui est un hachage des 2 précédents.


Ce n'est pas obligé d'être sur l'unicité. Je combine deux guidons pour simplifier mes structures de données. Le premier est un identifiant de récepteur public, le second est un identifiant de session privé d'expéditeur. Pour empêcher les expéditeurs non autorisés (sans identifiant de session valide) d'envoyer des données aux récepteurs arbitraires de leur choix, j'utilise des GUID combinés sous forme de clés dans les tables de routage sur le serveur.


11 Réponses :


1
votes

dépend de la plate-forme et des détails de ce que vous essayez de faire.

in .NET / C #, vous pourriez jeter une approche simple simple: xxx


0 commentaires

0
votes

Pourquoi ne pas essayer un simple opérateur, c'est-à-dire et, ou, XOR, etc. pour combiner les deux. Xor serait votre meilleur pari auquel j'imagine que j'imagine que la belle propriété de la quantité de résultat de l'une des deux entrées, vous obtiendrez l'autre.

Edit: Vous venez d'examiner cette solution, il y a un problème avec cela. Les valeurs devraient être normalisées. Jetez un coup d'œil à La réponse de Vinay pour une meilleure solution. < / p>


0 commentaires

3
votes

Vous ne pouvez pas convertir 2 GUDS de 128 bits en une valeur de 16 bits ou 32 bits et maintenez l'unicité. Pour votre application indiquée (valeur d'utilisation de l'URL), cela ne semble pas avoir de sens, car une valeur donnée dans l'URL pourrait mapper à n'importe quel nombre de combinaisons GUID. Avez-vous pensé cela?

La meilleure approche serait d'utiliser une recherche de raccourcissement de l'URL où vous générez un identifiant unique et de la cartographier aux GUDS si nécessaire - de la même manière que Bit.ly ou tinyurl.com .


0 commentaires

2
votes

En supposant que vous souhaitiez générer une valeur de 32 d'octet Vous pouvez simplement concaténer les GUID car ils sont 16 octet chacun. Si vous avez vraiment besoin d'une valeur 32 bit la seule solution que je vois génère vos propres valeurs 32 bits et stocke les GUID associés dans une base de données afin que vous puissiez les récupérer plus tard.


0 commentaires

17
votes

Pas jolie, mais cela fonctionne ..

 private static Guid MungeTwoGuids(Guid guid1, Guid guid2)
 {
     const int BYTECOUNT = 16;
     byte[] destByte = new byte[BYTECOUNT];
     byte[] guid1Byte = guid1.ToByteArray();
     byte[] guid2Byte = guid2.ToByteArray();
     
     for (int i = 0; i < BYTECOUNT; i++)
     {
         destByte[i] = (byte) (guid1Byte[i] ^ guid2Byte[i]);
     }
      return new Guid(destByte);
 }


0 commentaires

7
votes

Qu'en est-il de fractionnement des Guids en 2 morceaux de 8 octets chacun, convertissez-les en Ulong (8 octets), Xor les combine, puis concatez les 2 résultats.

public static Guid Combine(this Guid x, Guid y)
        {
            byte[] a = x.ToByteArray();
            byte[] b = y.ToByteArray();

            return new Guid(BitConverter.GetBytes(BitConverter.ToUInt64(a, 0) ^ BitConverter.ToUInt64(b, 8))
                .Concat(BitConverter.GetBytes(BitConverter.ToUInt64(a, 8) ^ BitConverter.ToUInt64(b, 0))).ToArray());
        }


1 commentaires

Il est important de noter qu'un XOR B n'est pas égal à B Xor A dans la mise en œuvre suggérée



0
votes

Voici une doublure pour vous:

g1.ToByteArray().Concat(g2.ToByteArray()).GetHashCode()


0 commentaires

2
votes

J'ai eu la nécessité de fusionner deux guidons ensemble pour créer un troisième GUID. Lorsque le troisième GUID (pas nécessairement unique) serait le même quel que soit la commande, les deux GUID originaux ont été fournis. Donc, je suis venu avec ceci: xxx


0 commentaires

3
votes
var a = Guid.NewGuid();
var b = Guid.NewGuid();
var hashOfXor = Xor(a, b).GetHashCode();


public static Guid Xor(Guid a, Guid b)
{
    unsafe
    {
        Int64* ap = (Int64*) &a;
        Int64* bp = (Int64*) &b;
        ap[0] ^= bp[0];
        ap[1] ^= bp[1];

        return *(Guid*) ap;
    }
}

3 commentaires

Ceci est juste triste, la réponse n'a pas d'appels de GC, aucune boucle, utilise le pipeline de cache de la CPU aussi bonne que possible. Obtient 0 upvotes. C'est juste faux.


probablement parce qu'il n'y a pas d'explication à côté du code


Oui, et devoir avoir à "dangereux" votre projet de fusion de 2 GUIDS peut être utile lorsque vous recherchez des performances, mais lorsque cela n'est pas critique, l'autre solution est plus amicale



0
votes
public static string Merge(Guid one, Guid two)
    {
        return new List<Guid>() { one, two }
            .OrderBy(x => x.GetHashCode())
            .Select(y => y.ToString().ToLowerInvariant())
            .Aggregate((a, b) => ${a.ToLowerInvariant()}_{b.ToLowerInvariant()}");
    }
So in my situation i needed to maintain order in order to make sure that the 2 Guids could be merged regardless of order. Therefore they have to be ordered. That was step one. Then, it's simply selecting the guids to string and for consitency (super important), I used string.ToLowerInvariant(). Then concatenated them using the .Aggregate function.

3 commentaires

Pourriez-vous ajouter un peu d'explication ou de commentaire pour votre code?


Ouais, donc dans ma situation, je devais maintenir l'ordre afin de s'assurer que les 2 GUID pouvaient être fusionnés indépendamment de l'ordre. Par conséquent, ils doivent être commandés. C'était la première étape. Ensuite, il suffit de sélectionner les GUDS à la chaîne et de la constitu ainsi (super important), j'ai utilisé string.tolowerinvariant (). Puis les concaténés à l'aide de la fonction .agregistrate.


Merci pour la réponse. Je voulais modifier votre réponse pour inclure le commentaire, au lieu d'avoir juste un bloc de code, afin qu'il soit plus facile pour les futurs visiteurs de comprendre.



1
votes

in .NET CORE 3 Nous pouvons utiliser sse2 code> / span code> pour accélérer les choses et éviter toutes les allocations. Ce code traite essentiellement un GUID code> comme 2 valeurs intT64 code> et exécute le XOR sur eux. SSE2 effectue le XOR dans une seule instruction de processeur (SIMD).

public static Guid Xor(this Guid a, Guid b)
{
    if (Sse2.IsSupported)
    {
        var result = Sse2.Xor(Unsafe.As<Guid, Vector128<long>>(ref a), Unsafe.As<Guid, Vector128<long>>(ref b));
        return Unsafe.As<Vector128<long>, Guid>(ref result);
    }

    var spanA = MemoryMarshal.CreateSpan(ref Unsafe.As<Guid, long>(ref a), 2);
    var spanB = MemoryMarshal.CreateSpan(ref Unsafe.As<Guid, long>(ref b), 2);

    spanB[0] ^= spanA[0];
    spanB[1] ^= spanA[1];

    return b;
}


0 commentaires