1. Introduction

Lorsqu'on veut envoyer du courrier électronique en utilisant directement Winsock et une connexion à un serveur SMTP, il peut être intéressant de vouloir envoyer des fichiers attachés.

Pour indiquer au serveur SMTP qu'on est en train d'expédier un fichier attaché, on utilise la syntaxe suivante lorsqu'on est en train de transmettre le corps du message:

 
TéléchargerCacherSélectionnez
  1. begin XXX filename  
  2. //ici le contenu encodé du fichier 
  3. `  
  4. end  

Filename est bien évidemment le nom du fichier (e.g. "monimage.jpg") et XXX correspond aux permissions UNIX d'un fichier dans le cas où celui-ci serait reçu par une machine UNIX (typiquement 664 pour un fichier et 744 pour un exécutable).

Cependant et comme toujours, il y a un hic. Il est impossible de transmettre un fichier binaire encodé sur 8 bits directement dans un courrier électronique qui ne supporte qu'un jeu de caractères de 7 bits (pas de caractères étendus). Et de plus, il ne faut utiliser que les caractères imprimables. Il faut donc procéder à un encodage.

Le principe de l'encodage est le suivant: on prend 3 octets de données (donc 3x8 bits) et on les transforme en 4 morceaux de 6 bits, qu'on complète par des 0 pour avoir un octet ASCII. Ensuite, on ajoute 32 au code ASCII obtenu pour avoir un caractère ASCII imprimable (les 32 premiers ne le sont pas).

La fonction ci-après prend un chemin de fichier (e.g "c:\image\image1.jpg") et retourne une chaîne contenant le fichier encodé.

 
TéléchargerCacherSélectionnez
  1. Public Function UUEncodeFile(strFilePath As String) As String  
  2.  
  3. Dim intFile As Integer     'le numéro de fichier pour Open()  
  4. Dim intTempFile As Integer 'idem pour le fichier temporaire  
  5. Dim lFileSize As Long      'taille du fichier  
  6. Dim strFileName As String  'nom du fichier  
  7. Dim strFileData As String  'le tampon pour l'encodage  
  8. Dim lEncodedLines As Long  'nombre de lignes traitées  
  9. Dim strTempLine As String  'un autre tampon  
  10. Dim i As Long              'compteur i  
  11. Dim j As Integer           'compteur j 
  12.  
  13. Dim strResult As String  
  14. '  
  15. 'On extrait le nom du fichier du chemin  
  16. strFileName = Mid$(strFilePath, InStrRev(strFilePath, "\") + 1)  
  17. '  
  18. 'On insère l'en-tête du fichier attaché: "begin 664 ..."  
  19. strResult = "begin 664 " + strFileName + vbLf  
  20. '  
  21. 'on trouve la taille du fichier  
  22. lFileSize = FileLen(strFilePath)  
  23. lEncodedLines = lFileSize \ 45 + 1  
  24. 'Les données sont encodées par morceaux de 45 octets, 
  25. 'on initialise donc le buffer à "45 blancs"  
  26. strFileData = Space(45)  
  27.   
  28. intFile = FreeFile  
  29.   
  30. Open strFilePath For Binary As intFile  
  31. For i = 1 To lEncodedLines  
  32.     'On lit le contenu du fichier par morceaux de 45 octets 
  33.     '  
  34.     If i = lEncodedLines Then 'si on est à la fin du fichier 
  35.         'Quand on atteint la fin du fichier, en général 
  36.         'il reste moins de 45 octets à traiter, on adapte 
  37.         'donc la taille du tampon  
  38.         strFileData = Space(lFileSize Mod 45)  
  39.     End If  
  40.     'On copie les 45 octets en memoire  
  41. Get intFile, , strFileData  
  42.     'Le premier symbole de la chaîne contient l'info  
  43.     'sur la quantité de symboles dans la chaîne encodée  
  44. strTempLine = Chr(Len(strFileData) + 32)  
  45.     '  
  46.     If i = lEncodedLines And (Len(strFileData) Mod 3) Then  
  47.         'Si c'est la dernière ligne qui est traitée et  
  48.         'la longueur n'est pas divisible par 3,   
  49.         'on rajoute 2 ou 3 blancs  
  50.         strFileData = strFileData + Space(3 - _  
  51.             (Len(strFileData) Mod 3))  
  52.     End If  
  53.  
  54.     For j = 1 To Len(strFileData) Step 3  
  55.         'On transforme 3x8 bits en 4x6 bits  
  56.         '  
  57.         '1er octet  
  58.         strTempLine = strTempLine + _  
  59.             Chr(Asc(Mid(strFileData, j, 1)) \ 4 + 32)  
  60.         '2e octet  
  61.         strTempLine = strTempLine + _  
  62.             Chr((Asc(Mid(strFileData, j, 1)) Mod 4) * 16 _  
  63.             + Asc(Mid(strFileData, j + 1, 1)) \ 16 + 32)  
  64.         '3e octet 
  65.         strTempLine = strTempLine + _  
  66.             Chr((Asc(Mid(strFileData, j + 1, 1)) Mod 16) * 4 _  
  67.             + Asc(Mid(strFileData, j + 2, 1)) \ 64 + 32)  
  68.         '4e octet 
  69.         strTempLine = strTempLine + _  
  70.             Chr(Asc(Mid(strFileData, j + 2, 1)) Mod 64 + 32)  
  71.     Next j  
  72.     'rajouter le code traité au résultat  
  73.     strResult = strResult + strTempLine + vbLf  
  74.     'réinitialiser le tampon  
  75.     strTempLine = ""  
  76. Next i  
  77. Close intFile  
  78. 'on rajoute le marqueur de fin  
  79. strResult = strResult & "'" & vbLf + "end" + vbLf  
  80. 'on renvoie la chaîne de caractères  
  81. UUEncodeFile = strResult  
  82.  
  83. End Function 

Bien sûr, ce code est un peu rudimentaire, mais il montre bien le principe de la compression UUCP.

Bon courage et bon développement,

grafikm_fr.