11
votes

Incrémenter un octet []

J'ai un octet [] testkey = nouvel octet [8];

Ceci commence évidemment avec tous les octets sous forme de 0. Je veux passer par tous les octets et incrémenter de 1 sur chaque itération de la boucle, donc éventuellement, je passe toutes les possibilités de la matrice d'octet. Je veux aussi faire cela aussi vite que possible. Oui j'essaie d'écrire un forcer brute.

Mise à jour J'ai eu la méthode dangereuse qui fonctionne, et c'est le plus rapide. Cependant, par mes calculs, il faudra 76 000 000 ans pour faire boucle en boucle en effectuant un cryptage des Cryptage sur chaque clé utilisant le .NET DescryptoServiceProvider. 10 000 cryptes prend 1,3 seconde. Merci pour toutes les réponses impressionnantes à la question la plus inutile jamais!


5 commentaires

Pour tester toutes les 2 ^ 64, les combinaisons feront très longtemps.


Il faudra environ sept ans seulement pour boucler les combinaisons, considérablement plus si vous faites réellement quelque chose avec chaque combinaison. La force brute ne semble pas être la bonne approche pour cela ...


Ouais, sauf si vous avez les ressources informatiques d'une agence gouvernementale ou d'une grande entreprise derrière vous, vous n'avez aucune chance de tester de manière exhaustive un espace de recherche de taille 2 ^ 64. Même si chaque test n'a pris qu'un seul cycle pour fonctionner sur une CPU moderne, il faudrait 71 000 ans pour finir de tester l'espace de recherche complet.


@Stephentyrone: Comment avez-vous trouvé la figure 71000 ans? 2 ^ 64 / 3E9 / 3600 / 24/365 ~ 195 ans.


désolé, signifiait 71 mille jours =)


11 Réponses :


12
votes

BTW; Il faut un lot em> de traitement pour vérifier 2 ^ 64 options ...

Eh bien, le le plus rapide em> peut être de simplement utiliser un int64 code > (AKA long code>) ou uint64 code> ( ulong code>) et utilisez ++ code>? Avez-vous vraiment besoin du octet [] code>? P>

comme une alternative hacky, que diriez-vous: P>

unsafe static void Test() {
    byte[] data = new byte[8];
    fixed (byte* first = data) {
        ulong* value = (ulong*)first;
        do {
            // use data here
            *value = *value + 1;
        } while (*value != 0);
    }
}


2 commentaires

Je pense que les frais généraux de la fixation de la matrice en mémoire pour l'utiliser dans un code dangereux dépasseraient l'avantage de pouvoir le traiter comme une ...


Vous devez utiliser long * dans le code dangereux, pas UINT *. Même si vous vous bouclez dans la déclaration fixe, il est étonnamment lent. Mon code géré pour augmenter la matrice est environ 200 fois plus rapide ...



-1
votes

bitconverter.toint64 / bitconverter.getbytes - convertir 8 octets vers exactement longtemps et l'incrémenter. Quand presque fait se convertir en octets. C'est le moyen le plus rapide du système


2 commentaires

bitconverter ? le plus rapide? Création d'un nouvel octet [] par appel est pas le plus rapide par aucun étirement.


L'idée était de faire des supports logiques - commencez à convertir (une fois!) Octets à long terme. Plusieurs fois augmentent autant que possible, à la fin (quand presque terminé et une fois!) Convertir en octets



1
votes
for (UInt64 i = 0; i < UInt64.MaxValue; i++)
{
    byte[] data = BitConverter.GetBytes(i)
}

4 commentaires

Cela crée un nouvel octet [] par appel, faisant beaucoup de travail pour l'allocation et la collecte des ordures; Il y a des moyens plus rapides utilisant un tableau fixe


Cette boucle sera soit faite en un rien de temps ni au printemps de l'année 7854.


Il suffit de boucler à travers les combinaisons prendra environ sept ans en utilisant la méthode plus rapide de ma réponse. Utilisation de bitconverter, il faudra environ 10000 ans ...


Pour être terminé dans 7 ans, vous devez traiter 2 ^ 64 / (7 * 365.25 * 24 * 3600 * 1000) = 83506006 par milliseconde. Vraiment?



3
votes

octet [8] est essentiellement une ulong, mais si vous en avez vraiment besoin pour être d'octet [8], vous pouvez utiliser

byte[] bytes = new byte[8];
ulong i = 0;
bytes = BitConverter.GetBytes(i);


0 commentaires

7
votes

C'est ainsi que vous augmentez la valeur dans la matrice: xxx

lorsque index est -1 après ce code, vous avez itéré toutes les combinaisons.

Ceci sera légèrement plus rapide que d'utiliser BitConverter, car il ne crée pas de nouveau tableau pour chaque itération.

EDIT:
Un essai de faible performance a montré qu'il s'agissait d'environ 1400 fois plus rapides que d'utiliser BitConverter ...


4 commentaires

J'ai suscité parce que je vois du potentiel ici. Le problème est que la déclaration est au mauvais endroit. Comme le code ne passera pas 1.


@ Makerofthings7: Merci pour la uppote. Je pense que vous avez mal compris le code. Cela augmentera la matrice d'une. Pour augmenter une autre étape, vous utilisez à nouveau le code. Si vous souhaitez l'utiliser dans une boucle, vous mettez le code dans la boucle.


Wow c'est rapide! Je suis arrivé à 1 milliard en 4,2 secondes!


Bien que le code dangereux de Marc au-dessus de l'image de 2,7 secondes pour le même nombre d'itérations.



4
votes

Quelle bonne question! Voici un moyen de le faire sans Code dangereux:

public struct LongAndBytes
{
    [FieldOffset(0)]
    public ulong UlongValue;
    [FieldOffset(0)]
    public byte Byte0;
    [FieldOffset(1)]
    public byte Byte1;
    [FieldOffset(2)]
    public byte Byte2;
    [FieldOffset(3)]
    public byte Byte3;
    [FieldOffset(4)]
    public byte Byte4;
    [FieldOffset(5)]
    public byte Byte5;
    [FieldOffset(6)]
    public byte Byte6;
    [FieldOffset(7)]
    public byte Byte7;

    public byte[] ToArray()
    {
        return new byte[8] {Byte0, Byte1, Byte2, Byte3, Byte4, Byte5, Byte6, Byte7};
    }
}


// ...

    LongAndBytes lab = new LongAndBytes();

    lab.UlongValue = 0;
    do {
        // stuff
        lab.UlongValue++;
    } while (lab.ULongValue != 0);


3 commentaires

octet [] B = nouvel octet [8] {byte0, byte1, byte2, byte3, byte4, byte5, byte6, byte7};


+1 Pour Awesomeness .. J'aime cette réponse, simple mais puissante.


La boucle pour manquera la dernière combinaison. Vous avez besoin d'une boucle différente où vous vérifiez après l'incrémentation de la valeur si elle a atteint zéro à nouveau.



2
votes

Vous pouvez extraire les octets à l'aide des opérateurs de bits: xxx

Ceci est moins "piraté", car il fonctionne d'abord sur un entier non signé 64 bits, puis extrayez les octets. Toutefois méfiez-vous de l'endianesse du processeur.


0 commentaires

1
votes
byte[] array = new byte[8];
int[] shifts = new int[] { 0, 8, 16, 24, 32, 40, 48, 56 };    
for (long index = long.MinValue; index <= long.MaxValue; index++)
{
    for (int i = 0; i < 8; i++)
    {
        array[i] = (byte)((index >> shifts[i]) & 0xff);
    }
    // test array
}

0 commentaires

1
votes
for (int i = 0; i < bytes.Length & 0 == ++bytes[i]; i++);
Should be as fast as the unsafe method and allows arrays of any size.

1 commentaires

Probablement la meilleure réponse. Pas de hacks, simple et rapide.



0
votes

Itération simple: xxx


0 commentaires

0
votes

Désolé pour le poste tardif, mais j'avais besoin de la fonctionnalité décrite aussi et de la mettre en œuvre de manière assez simple à mon avis. Peut-être que c'est utile pour quelqu'un d'autre aussi: xxx


0 commentaires