IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Sécurité Java Discussion :

chiffrement dechiffrement symétrique


Sujet :

Sécurité Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    9
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Septembre 2007
    Messages : 9
    Par défaut chiffrement dechiffrement symétrique
    Bonjour,pour effectuer mon chiffrement dechiffrement de fichier, j'utilise la classe suivante. Cependant j'ai un probleme : quand je fais le chiffrement et que je dechiffre le fichier obtenu sur une autre machine, ca marche plus alors que quand je fait le dechiffrement en local (c'est a dire sur la machine sur laquelle j'ai chiffré le document) ca marche.

    Que faire pour regler ce probleme ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
     
    /*
     * DesEncypter.java
     *
     * Created on 26 septembre 2007, 11:22
     *
     * To change this template, choose Tools | Template Manager
     * and open the template in the editor.
     */
     
    package Cipher;
     
     
    import javax.crypto.*;
    import javax.crypto.spec.*;
     
    import java.io.*;
    import IHM.*;
    import javax.swing.JFileChooser;
    /**
     *
     * @author user
     */
     
     
     
    public class Encrypter {
     
     
        // Buffer used to transport the bytes from one stream to another
        byte[] buf = new byte[1024];
     
        //Secret key used to cipher a stream
        public SecretKeySpec key;
     
     
        /**
         * Creates a new instance of DesEncypter
         */
        public Encrypter() {
        }
     
     
        public void SetSecretKeySpec(String stringKey, String algorithm) {
            try {
                key = new SecretKeySpec(stringKey.getBytes("ISO-8859-1"),algorithm);
                System.out.println("Create a "+stringKey.getBytes("ISO-8859-1").length+" key " + stringKey );
            } catch (UnsupportedEncodingException ex) {
                ex.printStackTrace();
            }
     
        }
     
        //main ciphering function
        public void encrypt(InputStream in, OutputStream out, String algorithm) {
            try {
     
                // bytes read from in will be encrypted
                System.out.println("inputStream before encryption is ==>"+in);
                in = getEncryptedInputStream(in,algorithm);
                System.out.println("inputStream after encryption is ==>"+in);
     
                // Read in the cleartext bytes and write to out to encrypt
                int numRead = 0;
                while ((numRead = in.read(buf)) >= 0) {
                    out.write(buf, 0, numRead);
                }
                out.close();
            } catch (java.io.IOException e) {
                e.printStackTrace();
            }
        }
     
        //main deciphering fonction
        public void decrypt(InputStream in, OutputStream out,String algorithm) {
            try {
     
                // Bytes written to out will be decrypted
                System.out.println("outputStream before decryption is ==>"+out);
                out = getDecryptedOutputStream(out,algorithm);
                System.out.println("outputStream after decryption is ==>"+out);
     
                // Read in the decrypted bytes and write the cleartext to out
                int numRead = 0;
                while ((numRead = in.read(buf)) >= 0) {
                    out.write(buf, 0, numRead);
                }
                out.close();
            } catch (java.io.IOException e) {
                e.printStackTrace();
            }
        }
     
     
        private InputStream getEncryptedInputStream(InputStream in , String algorithm) {
            System.out.println("\n inside getEncryptedInputStream before encryption in==>"+in);
            try {
                Cipher ecipher = Cipher.getInstance(algorithm);
                ecipher.init(Cipher.ENCRYPT_MODE, key);
                in = new CipherInputStream(in, ecipher);
     
            } catch (javax.crypto.NoSuchPaddingException e) {
                e.printStackTrace();
            } catch (java.security.NoSuchAlgorithmException e) {
                e.printStackTrace();
            } catch (java.security.InvalidKeyException e) {
                e.printStackTrace();
            }
            System.out.println("\n inside getEncryptedInputStream after encryption in==>"+in);
            return in;
        }
     
     
     
        private OutputStream getDecryptedOutputStream(OutputStream out, String algorithm) {
            System.out.println("\n inside getDecryptedOutputStream before decryption out==>"+out);
            try {
                Cipher dcipher = Cipher.getInstance(algorithm);
                dcipher.init(Cipher.DECRYPT_MODE, key);
                out = new CipherOutputStream(out, dcipher);
            } catch (javax.crypto.NoSuchPaddingException e) {
                e.printStackTrace();
            } catch (java.security.NoSuchAlgorithmException e) {
                e.printStackTrace();
            } catch (java.security.InvalidKeyException e) {
                e.printStackTrace();
            }
            System.out.println("\n inside getDecryptedOutputStream after decryption out==>"+out);
            return out;
        }
    }
    le code du GUI pour chiffrer
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
     
    /*
     * CipherGUI.java
     *
     * Created on 27 septembre 2007, 09:19
     */
     
    package IHM;
     
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import javax.swing.JFileChooser;
    import Cipher.*;
     
    /**
     *
     * @author  user
     */
    public class CipherGUI extends javax.swing.JFrame {
     
        String filePath;
        //length of the secretkey
        int secretKeyLength;
        int conventionalSecretKeyLengthInBytes;
     
        //name of the algorithm AES,DES,3DES,Blowfish
        String algorithm;
        // the secret key use to cipher a file
        String secretKey;
     
     
        /** Creates new form CipherGUI */
        public CipherGUI() {
            initComponents();
            _secretKey_textField.setEditable(false);
            filePath=null;
        }
     
        /** This method is called from within the constructor to
         * initialize the form.
         * WARNING: Do NOT modify this code. The content of this method is
         * always regenerated by the Form Editor.
         */
        // <editor-fold defaultstate="collapsed" desc=" Generated Code ">                          
        private void initComponents() {
            _filename_button = new javax.swing.JButton();
            _cipher_button = new javax.swing.JButton();
            _algorithm_comboBox = new javax.swing.JComboBox();
            _secretKey_textField = new javax.swing.JTextField();
            _filename_label = new javax.swing.JLabel();
            jScrollPane1 = new javax.swing.JScrollPane();
            _infos_jtextArea = new javax.swing.JTextArea();
            _algorithm_length_comboBox = new javax.swing.JComboBox();
            _secretKey_label = new javax.swing.JLabel();
            _analyse_button = new javax.swing.JButton();
     
            setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
            addMouseListener(new java.awt.event.MouseAdapter() {
                public void mouseClicked(java.awt.event.MouseEvent evt) {
                    formMouseClicked(evt);
                }
            });
     
            _filename_button.setText("Choisir le fichier \u00e0 chiffrer");
            _filename_button.addMouseListener(new java.awt.event.MouseAdapter() {
                public void mouseClicked(java.awt.event.MouseEvent evt) {
                    _filename_buttonMouseClicked(evt);
                }
            });
     
            _cipher_button.setText("Chiffrer");
            _cipher_button.addMouseListener(new java.awt.event.MouseAdapter() {
                public void mouseClicked(java.awt.event.MouseEvent evt) {
                    _cipher_buttonMouseClicked(evt);
                }
            });
     
            _algorithm_comboBox.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "", "aes", "blowfish", "des", "desede" }));
            _algorithm_comboBox.addItemListener(new java.awt.event.ItemListener() {
                public void itemStateChanged(java.awt.event.ItemEvent evt) {
                    _algorithm_comboBoxItemStateChanged(evt);
                }
            });
     
            _secretKey_textField.setHorizontalAlignment(javax.swing.JTextField.CENTER);
            _secretKey_textField.setText("A1B2C3D4E5F6G7H8I9J10K11L12M13N14O15P16Q17R18");
     
            _filename_label.setText("Selected filename is not defined");
     
            _infos_jtextArea.setColumns(20);
            _infos_jtextArea.setRows(5);
            jScrollPane1.setViewportView(_infos_jtextArea);
     
            _algorithm_length_comboBox.addItemListener(new java.awt.event.ItemListener() {
                public void itemStateChanged(java.awt.event.ItemEvent evt) {
                    _algorithm_length_comboBoxItemStateChanged(evt);
                }
            });
     
            _secretKey_label.setText("Secret key length not defined");
     
            _analyse_button.setText("Analyser");
            _analyse_button.addMouseListener(new java.awt.event.MouseAdapter() {
                public void mouseClicked(java.awt.event.MouseEvent evt) {
                    _analyse_buttonMouseClicked(evt);
                }
            });
     
            javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
            getContentPane().setLayout(layout);
            layout.setHorizontalGroup(
                layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(layout.createSequentialGroup()
                    .addContainerGap()
                    .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                        .addGroup(layout.createSequentialGroup()
                            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                .addComponent(_filename_button, javax.swing.GroupLayout.DEFAULT_SIZE, 382, Short.MAX_VALUE)
                                .addComponent(_filename_label, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 382, Short.MAX_VALUE)
                                .addGroup(layout.createSequentialGroup()
                                    .addGap(35, 35, 35)
                                    .addComponent(_algorithm_comboBox, javax.swing.GroupLayout.PREFERRED_SIZE, 123, javax.swing.GroupLayout.PREFERRED_SIZE)
                                    .addGap(49, 49, 49)
                                    .addComponent(_algorithm_length_comboBox, javax.swing.GroupLayout.PREFERRED_SIZE, 129, javax.swing.GroupLayout.PREFERRED_SIZE)
                                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 46, javax.swing.GroupLayout.PREFERRED_SIZE)))
                            .addGap(25, 25, 25))
                        .addGroup(layout.createSequentialGroup()
                            .addComponent(_secretKey_textField, javax.swing.GroupLayout.DEFAULT_SIZE, 382, Short.MAX_VALUE)
                            .addGap(25, 25, 25))
                        .addGroup(layout.createSequentialGroup()
                            .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 382, Short.MAX_VALUE)
                            .addGap(25, 25, 25))
                        .addGroup(layout.createSequentialGroup()
                            .addComponent(_cipher_button, javax.swing.GroupLayout.DEFAULT_SIZE, 382, Short.MAX_VALUE)
                            .addGap(25, 25, 25))
                        .addGroup(layout.createSequentialGroup()
                            .addComponent(_secretKey_label, javax.swing.GroupLayout.DEFAULT_SIZE, 185, Short.MAX_VALUE)
                            .addGap(222, 222, 222))
                        .addGroup(layout.createSequentialGroup()
                            .addComponent(_analyse_button, javax.swing.GroupLayout.DEFAULT_SIZE, 382, Short.MAX_VALUE)
                            .addGap(25, 25, 25))))
            );
            layout.setVerticalGroup(
                layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(layout.createSequentialGroup()
                    .addGap(20, 20, 20)
                    .addComponent(_filename_button)
                    .addGap(16, 16, 16)
                    .addComponent(_filename_label)
                    .addGap(15, 15, 15)
                    .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                        .addComponent(_algorithm_comboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addComponent(_algorithm_length_comboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 34, Short.MAX_VALUE)
                    .addComponent(_analyse_button)
                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                    .addComponent(_secretKey_label)
                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                    .addComponent(_secretKey_textField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addGap(30, 30, 30)
                    .addComponent(_cipher_button)
                    .addGap(23, 23, 23)
                    .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addGap(48, 48, 48))
            );
            pack();
        }// </editor-fold>                        
     
        private void _analyse_buttonMouseClicked(java.awt.event.MouseEvent evt) {                                             
    // TODO add your handling code here:
            if (!_algorithm_length_comboBox.getSelectedItem().toString().equals("taille")) {
                int conventionalSecretKeyLengthInBits = Integer.parseInt( _algorithm_length_comboBox.getSelectedItem().toString());
                conventionalSecretKeyLengthInBytes = conventionalSecretKeyLengthInBits/8;
                _secretKey_label.setText("Entrer une cle de longeur "+conventionalSecretKeyLengthInBytes);
                _secretKey_textField.setEditable(true);
            }
        }                                            
     
        private void _algorithm_length_comboBoxItemStateChanged(java.awt.event.ItemEvent evt) {                                                            
    // TODO add your handling code here:
        }                                                           
     
        private void _algorithm_comboBoxItemStateChanged(java.awt.event.ItemEvent evt) {                                                     
    // TODO add your handling code here:
            algorithm = _algorithm_comboBox.getSelectedItem().toString();
     
            if (algorithm.equals("aes")) {
                _algorithm_length_comboBox.removeAllItems();
                _algorithm_length_comboBox.addItem("taille");
                _algorithm_length_comboBox.addItem("128");
                _algorithm_length_comboBox.addItem("192");
                _algorithm_length_comboBox.addItem("256");
            }
            if (algorithm.equals("des")) {
                _algorithm_length_comboBox.removeAllItems();
                _algorithm_length_comboBox.addItem("taille");
                _algorithm_length_comboBox.addItem("64");
            }
            if (algorithm.equals("desede")) {
                _algorithm_length_comboBox.removeAllItems();
                _algorithm_length_comboBox.addItem("taille");
                _algorithm_length_comboBox.addItem("192");
            }
            if (algorithm.equals("blowfish")) {
                _algorithm_length_comboBox.removeAllItems();
                _algorithm_length_comboBox.addItem("taille");
                _algorithm_length_comboBox.addItem("128");
                _algorithm_length_comboBox.addItem("192");
                _algorithm_length_comboBox.addItem("256");
                _algorithm_length_comboBox.addItem("320");
                _algorithm_length_comboBox.addItem("384");
                _algorithm_length_comboBox.addItem("448");
            }
        }                                                    
     
        private void _filename_buttonMouseClicked(java.awt.event.MouseEvent evt) {                                              
    // TODO add your handling code here:
            JFileChooser choix = new JFileChooser();
            choix.setAccessory(new FilePreview(choix));
            int retour = choix.showOpenDialog(this);
            if (retour == JFileChooser.APPROVE_OPTION) {
                // un fichier a été choisi (sortie par Ouvrir)
                filePath=choix.getSelectedFile().getAbsolutePath();// chemin absolu du fichier choisi
                this._filename_label.setText("fichier a chiffrer "+filePath);
            } else ; // pas de fichier choisi
        }                                             
     
        private void _cipher_buttonMouseClicked(java.awt.event.MouseEvent evt) {                                            
    // TODO add your handling code here:
            algorithm = _algorithm_comboBox.getSelectedItem().toString();
            secretKey = _secretKey_textField.getText();
            secretKeyLength = secretKey.length();
     
            if (secretKeyLength > conventionalSecretKeyLengthInBytes) {
                secretKey = secretKey.substring(0,conventionalSecretKeyLengthInBytes);
                _infos_jtextArea.setText("la secret key est trop longue et sera tronquee. Secretkey utilisee\n"+secretKey +"\n"+secretKey.length());
            }
     
            if (secretKeyLength < conventionalSecretKeyLengthInBytes) {
                int temp = conventionalSecretKeyLengthInBytes - secretKeyLength;
                String concat="0";
                for (int i = 1 ; i < temp ; i++)
                    concat = concat+"0";
                secretKey = secretKey + concat;
                System.out.println(secretKeyLength +" + "+concat.length());
                _infos_jtextArea.setText("la secret key est trop courte des 0 seront ajoutes.\nSecretkey utilisee\n"+secretKey +"\n"+secretKey.length());
            }
     
     
            if (secretKey.length() == conventionalSecretKeyLengthInBytes ) {
                _infos_jtextArea.setText("longeur de clé correcte \n"+secretKey +"\n"+secretKey.length());
                // Create encrypter/decrypter class
                Encrypter encrypter = new Encrypter();
                encrypter.SetSecretKeySpec(secretKey,algorithm);
                // Encrypt
                if(!filePath.equals(null)) {
                    System.out.println("encrypting the file");
                    try {
                        encrypter.encrypt(new FileInputStream(filePath), new FileOutputStream(filePath+algorithm+(conventionalSecretKeyLengthInBytes*8)),algorithm);
                    } catch (FileNotFoundException ex) {
                        ex.printStackTrace();
                    }
                } else
                    _infos_jtextArea.setText("pas de fichier selectionne");
     
            } else
                _infos_jtextArea.setText(secretKey.length()+ " requiere " +conventionalSecretKeyLengthInBytes);
     
     
        }                                           
     
        private void formMouseClicked(java.awt.event.MouseEvent evt) {                                  
    // TODO add your handling code here:
     
        }                                 
     
        /**
         * @param args the command line arguments
         */
        public void Launch() {
            java.awt.EventQueue.invokeLater(new Runnable() {
                public void run() {
                    new CipherGUI().setVisible(true);
                }
            });
        }
     
        // Variables declaration - do not modify                     
        private javax.swing.JComboBox _algorithm_comboBox;
        private javax.swing.JComboBox _algorithm_length_comboBox;
        private javax.swing.JButton _analyse_button;
        private javax.swing.JButton _cipher_button;
        private javax.swing.JButton _filename_button;
        private javax.swing.JLabel _filename_label;
        private javax.swing.JTextArea _infos_jtextArea;
        private javax.swing.JLabel _secretKey_label;
        private javax.swing.JTextField _secretKey_textField;
        private javax.swing.JScrollPane jScrollPane1;
        // End of variables declaration                   
     
    }
    pour dechiffrer il suffit de modifier le GUI du chiffrement et notament la ligne encrypter.encrypt .. par encrypter.decrypt(cipherSource, destination,algo)

  2. #2
    Membre éclairé Avatar de Razgriz
    Profil pro
    Professeur / chercheur en informatique / mathématiques
    Inscrit en
    Avril 2006
    Messages
    391
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Professeur / chercheur en informatique / mathématiques

    Informations forums :
    Inscription : Avril 2006
    Messages : 391
    Par défaut
    Grrrrrrrrrrr, je sens que je vais faire un carnage...

    J'ai posté des classes pour le cryptage dans la section contribuez (Posetz vos sources java) , il y a tout ce dont tu as besoin pour résoudre ton problème, peut-être qu'en cherchant tu aurais trouvé... Ton erreur vient d'une mauvaise utilisation de la classe Cipher. Et ensuite le DES est un algorithme obsolète qui n'est plus considéré comme sur depuis longtemps. Utilise ma classe SymetricEncryptor (tu auras besoin de CipherEncryptor et de FileEncryptor aussi).

    Sinon de manière plus aimable je me méfierais de la classe CipherIn/Outputstream, elle contient des bugs pour le cryptage de certains algorithmes sous certaines conditions, comme le RSA, il faut donc l'utiliser avec précaution.

    Sur ce, a+, j'espère avoir répondu à tes questions.

Discussions similaires

  1. algorithme de chiffrement symétrique
    Par kadis500 dans le forum C++
    Réponses: 2
    Dernier message: 25/04/2010, 21h44
  2. Question sur le chiffrement/dechiffrement
    Par deglingo592003 dans le forum Sécurité
    Réponses: 5
    Dernier message: 05/08/2009, 12h03
  3. choix algo chiffrement symétrique
    Par sky_java_seb dans le forum Sécurité
    Réponses: 0
    Dernier message: 01/02/2009, 17h10
  4. [SECURITE] Chiffrement 3DES C et dechiffrement JAVA
    Par dams50 dans le forum Algorithmes et structures de données
    Réponses: 1
    Dernier message: 12/12/2005, 21h58
  5. Réponses: 6
    Dernier message: 12/12/2005, 21h50

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo