概述
  《思考-RBAC 中对于权限编码部分的压缩处理》近段时间重新学习了一下压缩算法,突然想到在平时的程序设计中能否对其进行应用,进而想到最基础的 RBAC 权限设计,可否将大量的一对多的关联关系部分数据进行压缩,本文介绍只是一种思路,作者并未在真实环境对此进行应用。
背景
  在最基础的 RBAC 权限设计中,有用户与角色的关联表和角色与权限的关联表,这两个关联表都是多对多的,极端情况下关联表的数据量会越来越大,可否将数据进行优化?是作者编写本文的一个背景思考。
  在 Linux 系统中对于文件的权限就是用位计算实现的,需要控制读、写、执行 3 个权限,仅需用 3 位二进制数来表示,可否将位运算的思想加入到权限设计中。
实现
  基于如上两个背景思考,开始了一些技术预演,包括位运算的一些示例和一个更好的压缩/解压算法,减少位向量在数据库中的存储。
  代码如下,定义 BitSet 表示权限集合,并且对 BitSet 进行数据初始化,之后进行压缩和解压,并判断某一个权限编码是否在解压后的位向量中。
 package com.pap.base.util.bitset;
import org.junit.Test;
import java.io.ByteArrayInputStream;import java.io.ByteArrayOutputStream;import java.io.IOException;import java.util.Base64;import java.util.BitSet;import java.util.zip.GZIPInputStream;import java.util.zip.GZIPOutputStream;
public class BitSetCompressTest {
    // @Test    public void test() {        // 创建一个 BitSet,表示权限集合        BitSet permissionSet = new BitSet();        for (int i = 0; i < 1000000; i++) {            permissionSet.set(i);        }
        // 将 BitSet 压缩为字符串        String compressedString = compressBitSet(permissionSet);        // 解压        BitSet loadedPermissionSet = decompressBitSet(compressedString);
        int permissionToCheck = 888;        if (loadedPermissionSet.get(permissionToCheck)) {            System.out.println("权限存在: " + permissionToCheck);        } else {            System.out.println("权限不存在: " + permissionToCheck);        }    }
    // 将 BitSet 压缩为 GZIP 压缩后再进行 Base64 编码的字符串    private static String compressBitSet(BitSet bitSet) {        byte[] byteArray = bitSet.toByteArray();        try {            ByteArrayOutputStream baos = new ByteArrayOutputStream();            try (GZIPOutputStream gzipOutputStream = new GZIPOutputStream(baos)) {                gzipOutputStream.write(byteArray);            }            return Base64.getEncoder().encodeToString(baos.toByteArray());        } catch (IOException e) {            e.printStackTrace();            return "";        }    }
    // 将 GZIP 压缩后的 Base64 编码的字符串解压为 BitSet    private static BitSet decompressBitSet(String compressedString) {        byte[] compressedByteArray = Base64.getDecoder().decode(compressedString);        try (ByteArrayInputStream bais = new ByteArrayInputStream(compressedByteArray);             GZIPInputStream gzipInputStream = new GZIPInputStream(bais)) {            byte[] buffer = new byte[1024];            ByteArrayOutputStream baos = new ByteArrayOutputStream();            int len;            while ((len = gzipInputStream.read(buffer)) != -1) {                baos.write(buffer, 0, len);            }            return BitSet.valueOf(baos.toByteArray());        } catch (IOException e) {            e.printStackTrace();            return new BitSet();        }    }
}
       复制代码
 参考
http://pap-docs.pap.net.cn/
https://gitee.com/alexgaoyh/
评论