Bits

Manipulation des bits en Java

Ce site ne sera plus alimenté de contenu après août 2014. Tous les nouveaux articles seront redigés pour www.waitingforcode.com

En PHP rarement on a besoin de manipuler les bits. C'est pourquoi certaines notions de leur gestion en Java peut être au début un peu confuses.

Tout d'abord, regardons les exemples d'utilisation des bits. Les opérations sur les bits sont le plus souvent utilisées dans la programmation du bas niveau ou embarquée. Elles trouvent donc leur usage dans de tels domaines que :
- communication avec des périphériques
- traitement des fichiers au format binaire
- gestion des masques binaires
- utilisation dans certains algorithmes de compression (codage de Huffman)
- programmation JavaScript (exemple sur Google Calendar )

On verra l'utilisation des bits sur le cas des masques binaires. On peut les utiliser dans le monde des applications réelles pour, par exemple, gérer les droits d'accès à une ressource. Constatons l'implémentation du CRUD grâce aux bits sur un exemple :

public class BitMasks {
    public static void main(String[] args) {
        int maskAddAllowed = 4;
        int maskEditAllowed = 16;
        int maskDeleteAllowed = 32;  

        int maskTotal = maskAddAllowed | maskEditAllowed | maskDeleteAllowed;

        System.out.println("Mask of super administrator " + maskTotal);

        int writerPermissions = 0;
        int moderatorPermissions = 0;

        System.out.println("Writer's default permissions are " + writerPermissions);
        System.out.println("Moderator's default permissions are " + moderatorPermissions);

        writerPermissions |= maskAddAllowed;
        writerPermissions |= maskEditAllowed; 

        moderatorPermissions |= maskEditAllowed;
        moderatorPermissions |= maskDeleteAllowed;

        System.out.println("Writer's final permissions are " + writerPermissions);
        System.out.println("Moderator's final permissions are " + moderatorPermissions);

        System.out.println("Permissions checking \n");
        System.out.println("Writer can add an article ? " + isPermitted(writerPermissions, maskAddAllowed));
        System.out.println("Moderator can add an article ? " + isPermitted(moderatorPermissions, maskAddAllowed));
        System.out.println("Writer can edit an article ? " + isPermitted(writerPermissions, maskEditAllowed));
        System.out.println("Moderator can edit an article ? " + isPermitted(moderatorPermissions, maskEditAllowed));
        System.out.println("Writer can remove an article ? " + isPermitted(writerPermissions, maskDeleteAllowed));
        System.out.println("Moderator can remove an article ? " + isPermitted(moderatorPermissions, maskDeleteAllowed));
    }

    private static boolean isPermitted(int userPerm, int systemPerm) {
        return ((userPerm & systemPerm) == systemPerm);
    }
}

Le résultat est suivant :

Mask of super administrator 52
Writer's default permissions are 0
Moderator's default permissions are 0
Writer's final permissions are 20
Moderator's final permissions are 48
Permissions checking

Writer can add an article ? true
Moderator can add an article ? false
Writer can edit an article ? true
Moderator can edit an article ? true
Writer can remove an article ? false
Moderator can remove an article ? true

Comment cela fonctionne ? Dans un article consacré aux shift opérations en Java on a brièvement expliqué certaines manipulations utilisées dans l'exemple ci-dessus. Les fragments contenant |= illustrent l'utilisation de l'opérateur inclusif OR. Expliquons comment ça marche.

Représentations binaires des chiffres utilisés dans l'exemple sont :
- pour 4 : 0000 1000
- pour 16 : 0001 0000
- pour 32 : 0010 0000
- pour 48 : 0011 0000

Regardons ce qui se passe si l'on compare deux chiffres avec l'opérateur AND (&). Dans le code d'exemple, la vérification se déroule dans la méthode isPermitted(). Analysons deux exemples où un retourne vraie, l'autre faux.

1 : (4 & 20) == 4 = true

1.1 : 4 & 20 = 00001000

Chiffre 4 0 0 0 0 1 0 0 0
Chiffre 20 0 0 0 1 1 0 0 0
(4 & 20) 0 0 0 0 1 0 0 0

1.2 (4 & 20) == 4 = true

(4 & 20) 0 0 0 0 1 0 0 0
4 0 0 0 0 1 0 0 0
Résultat true true true true true true true true

2 : (48 & 4) == 4 = false

2.1 : 48 & 4 = 00001000

Chiffre 48 0 0 1 1 0 0 0 0
Chiffre 4 0 0 0 0 1 0 0 0
(48 & 4) 0 0 0 0 0 0 0 0

2.2 (48 & 4) == 4 = false

(48 & 4) 0 0 0 0 0 0 0 0
4 0 0 0 0 1 0 0 0
Résultat true true true true false true true true

On peut constater que l'opérateur AND compare deux représentations binaires des chiffres. Si les deux caractères comparés sont les 1, il retourne 1. Sinon, il affiche 0. Quand une nouvelle représentation binaire générée, elle est comparée à celle représentant les droits d'accès. Si la comparaison bit par bit (par exemple 0 == 0 = true, 1 == 0 = false etc.) retourne en sa globalité vrai, l'utilisateur peut effectuer une action.

Bartosz KONIECZNY Informations sur le langage

Une question ? Une remarque ?

*

*

Un conseil MySQL

Comment convertir le timestamp en Unix temps ?

La fonction UNIX_TIMESTAMP() permet cette opération.