二进制内容的 能否可视化?  网上的资料比较少啊!

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

有时候通过 可视化工具,比如redis DesktopManager 查看 redis 的key 的值的时候,发现是 二进制内容, 如下:

出现二进制的内容, 丝毫不奇怪,因为我set的时候value就是key。怪的是, 为什么有的 英文字母 能够展示出来, 其他就都是\x ,可能是 这个工具本身做了一些处理吧。  但其实不然, 如果命令行登录进去一看,发现也是一样的 结果:

127.0.0.1:[]> get DISCUSS:TOPIC:3d28016e7cb34119aab718da2d4d1fe5::count
"\xac\xed\x00\x05sr\x00\x11java.lang.Integer\x12\xe2\xa0\xa4\xf7\x81\x878\x02\x00\x01I\x00\x05valuexr\x00\x10java.lang.Number\x86\xac\x95\x1d\x0b\x94\xe0\x8b\x02\x00\x00xp\x00\x00\x00\x00"

可以看到其中 java.lang.Integer java.lang.Number 都是 类名。

另外注意到 如果 notepad++打开一个二进制文件, 比如class文件,那么也会看到这样的 乱码和 英文夹杂的情况。 为什么会这样 ?

写个程序测试下:

package com.lkk;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.plugins.Page;
import com.lkk.ppm.discuss.domain.entity.ELComment;
import io.lettuce.core.RedisClient;
import io.lettuce.core.RedisURI;
import org.apache.commons.codec.binary.Hex;
import org.junit.Assert;
import org.junit.Test;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.connection.RedisStringCommands;
import org.springframework.data.redis.connection.lettuce.LettuceConnection;
import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.util.ByteUtils; import javax.xml.bind.DatatypeConverter;
import java.io.ByteArrayInputStream;
import java.io.FileInputStream;
import java.net.URL;
import java.nio.ByteBuffer; /**
 * @author Administrator
 * @date 2019/9/5 0005 12:40
 * @Description
 */
public class TestRedisSerializer {     private static final int CURRENT = 111;
    private static final int SIZE = 222;     static RedisSerializer serial;
    static RedisSerializationContext.SerializationPair serializationPair;
    static RedisStringCommands redisStringCommands;     static {
        RedisURI redisURI = RedisURI.create("192.168.11.200", 6380);
        redisURI.setPassword("Redis!123");
        long jedis = 100000L;
        RedisConnection connection = new LettuceConnection(jedis, RedisClient.create(redisURI));
        connection.select(2);         redisStringCommands = connection.stringCommands();
        // 切换 序列化组件
        serial = new JdkSerializationRedisSerializer();// 默认就是 JdkSerializationRedisSerializer //          StringRedisSerializer 只能够序列化字符串, 不能序列化 对象。 好像没啥用!
//       serial = new StringRedisSerializer();         // GenericFastJsonRedisSerializer 可以将对象序列化为 json格式字符串
//        serial = new GenericFastJsonRedisSerializer();         serializationPair = RedisSerializationContext.SerializationPair.fromSerializer(serial);
    }     @Test
    public void testHex() throws Exception {
//        ByteUtils.getBytes(this.cacheConfig.getValueSerializationPair().write(value)
//         ByteUtils.getBytes(this.cacheConfig.getValueSerializationPair().write(value)
//        org.apache.commons.compress.utils.ByteUtils.         String foo = "hello";
        byte[] bytes = foo.getBytes("unicode");
        bytes = foo.getBytes();
//        bytes = foo.getBytes("gb2312");         /**
         * 虽然foo 是纯英文字母,但 下面的方法都 无法将bytes 还原到上面的hello 了。。 TODO
         */
        System.out.println( Hex.encodeHexString( bytes ) );// 结果是 纯16进制的内容 68656c6c6f,不带 \ x 无法查看
        String s = DatatypeConverter.printHexBinary(bytes);;// 结果是 纯16进制的内容 68656c6c6f, 无法查看
        System.out.println("s = " + s);
//        byte[] decoded = Hex.decodeHex("00A0BF");
//        System.out.println("decoded = " + new String(decoded));         /**
         *  还原到上面的hello
         */
        dumpBytesToHex(bytes);         // 尝试读取class文件
        // 当前文件
        String fileFullName = "E:\\dev\\erdp2\\erdp_discuss\\erdp_discuss_service\\target\\test-classes\\com\\lkk\\TestRedisSerializer.class";
        FileInputStream fis = new FileInputStream(fileFullName);
//        fis.getChannel()
//        ByteArrayInputStream
//        fis.read()
        int available = fis.available();
        byte[] classBytes = new byte[available];
        int read = fis.read(classBytes);         String s1 = dumpBytesToHex(classBytes);// 除了换行符,基本上 得到了 和 notepad++ 一样的效果。
        Assert.assertTrue(s1.contains("TestRedisSerializer"));         ClassLoader classLoader = TestRedisSerializer.class.getClassLoader();     }     @Test
    public void testWrite() throws Exception {
        String key = "RESOURCE:ITEM:FILE::9fd04b83e33844b1a21ffa1c05978fc1_content.js";
//        key = "RESOURCE:ITEM:FILE::3fa4bbdff660490092ba9af971980838_template.html";
//        key = "DISCUSS:TOPIC:3d28016e7cb34119aab718da2d4d1fe5::count";
        key = "DISCUSS:TOPIC:xxx::count";
        write(key);
    }
    
    private void write(Object key) throws Exception {
        /**
         * CURRENT SIZE 测试read 要用到
         */
        Page<ELComment> page = new Page<>(CURRENT, SIZE);
        String s2 = JSONObject.toJSONString(page);
//        byte[] bytes = ByteUtils.getBytes(serializationPair.write(key));         //如果是 JdkSerializationRedisSerializer : write 1 结果是  "\xac\xed\x00\x05sr\x00\x11java.lang.Integer\x12\xe2\xa0\xa4\xf7\x81\x878\x02\x00\x01I\x00\x05valuexr\x00\x10java.lang.Number\x86\xac\x95\x1d\x0b\x94\xe0\x8b\x02\x00\x00xp\x00\x00\x00\x01"
//        byte[] bytes = ByteUtils.getBytes(serializationPair.write(1));         byte[] bytes = ByteUtils.getBytes(serializationPair.write(page));
        Boolean set = redisStringCommands.set(key.toString().getBytes(), bytes);
//        System.out.println("set = " + set);
//        byte[] bytes = ByteUtils.getBytes(RedisSerializationContext.SerializationPair.fromSerializer(serial).write(new String("abc阿斯蒂芬")));
//        System.out.println("bytes = " + bytes.length);
        String s = dumpBytesToHex(bytes);
        Assert.assertTrue(s.contains("com.baomidou.mybatisplus.plugins.Page"));
    }
    
    @Test
    public void testRead() throws Exception {
        String key = "DISCUSS:TOPIC:xxx::count";
        read(key);
    }     private void read(String key) {
        byte[] bytes1 = redisStringCommands.get(key.getBytes());
        System.out.println("TestRedis.aaa");
        System.out.println("bytes1 === " + new String(bytes1));// 直接打印 二进制内容
        System.out.println("TestRedis.bbb");
        dumpBytesToHex(bytes1);// 打印 16 进制内容         Page<ELComment> read = (Page<ELComment>) serializationPair.read(ByteBuffer.wrap(bytes1));
        System.out.println("read = " + read);
        int pages = read.getPages();
        int size = read.getSize();
        System.out.println("size = " + size);
        Assert.assertEquals(read.getSize(), SIZE);
        Assert.assertEquals(read.getCurrent(), CURRENT);
    }     /**
     * 转换为16进制 再打印
     * @param bytes
     * @return
     */
    public static String dumpBytesToHex(byte[] bytes) {
        String s = bytesToHex(bytes);
        System.out.println("Hex String:\n" + s);
        return s;
    }     private static final char[] HEX_ARRAY = "0123456789ABCDEF".toCharArray();     public static String bytesToHex66(byte[] bytes) {
        StringBuffer sb = new StringBuffer();
        char[] hexChars = new char[bytes.length * 2];
        for (int j = 0; j < bytes.length; j++) {
            byte aByte = bytes[j];
            if (aByte > 33 && aByte < 128) {
                sb.append((char) aByte);
                continue;
            }
            int v = bytes[j] & 0xFF;
            hexChars[j * 2] = HEX_ARRAY[v >>> 4];
            hexChars[j * 2 + 1] = HEX_ARRAY[v & 0x0F];             String hex = Integer.toHexString(aByte & 0xFF);
            sb.append("\\x");
            sb.append(hex);
            if (hex.length() < 2) {
                if (aByte == 0) {
//                    continue; // Fixme ,
                } else {
                }
                sb.append(0); // Fixme ,
            }
        }
//        return new String(hexChars);
        return sb.toString();
    }     /**
     * @param bytes
     * @return
     */
    public static String bytesToHex(byte[] bytes) {
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < bytes.length; i++) {
            byte aByte = bytes[i];             /**
             * 这一段是做 ascii码字符 转换
             */
            if (aByte > 33 && aByte < 128) {
                sb.append((char) aByte);
                continue;
            }
            String hex = Integer.toHexString(aByte & 0xFF);
            sb.append("\\x");
            sb.append(hex);
            if (hex.length() < 2) {
                if (aByte == 0) {
//                    continue;
                } else {
                }
                sb.append(0);
            }
        }
        return sb.toString();
    } }

Binary Viewer 查看的 结果是:

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

总结:

二进制的内容, 可以用hex 查看/编辑器 进行查看, 一般情况下 是无法直接转换为 字符串的!! 二进制的内容 如果 用hex 查看器查看,发现确实有字符串,那么可能就是 它本身就是 刚好被查看器支持直接展示了吧。

网上很多的二进制转 16进制的 所谓工具, 其实 其结果并不是Redis 客户端展示的结果,不是我想要的。。 因为它对 字符串的不能直接解析出来。。

16 进制不能阅读, 可以尝试转换为ascii。 二进制其实就是内存的内容,任何文件都可以转换为二进制。 软件把它展示出来, 它需要按照特定的 编码格式。文本内容是 天生可以用 文本编辑器 查看的。 其他的 , 比如 图片, 需要图片查看器, 依次类推。 class文件 呢?   其实也有专门的 查看器。。

注意到 其中 \ x 其实是一个 方便终端展示的一个 程序添加的 字符。 并不是 二进制内容自带的。

StringRedisTemplate默认使用的是StringRedisSerializer, 默认只能用来存储value类型为 string 的值。。

Redis 自带的序列化器是的JdkSerializationRedisSerializer,也就是我们 生成我们 class 文件的 二进制序列化器。 其生成的结果很臃肿, 效率是比较低的!

参考:

https://www.jianshu.com/p/23f2c4c92093

https://blog.csdn.net/Eric_Blog_CSDN/article/details/78904679

关于Redis 二进制内容的 可视化尝试的更多相关文章

  1. Redis二进制安全

    为了便于理解,举一个例子: 在很多编辑器中,都会默认/n是换行字符,也就意味着一串字符存进去,涉及/n都会做一个默认的转义处理,这在编辑语言中,C也有这个特性,例如字符串Hello,\0 World! ...

  2. Redis安装教程及可视化工具RedisDesktopManager下载安装

    Redis安装教程: 1. Windows下安装教程: 下载:https://github.com/MSOpenTech/redis/releases Redis 支持 32 位和 64 位.这个需要 ...

  3. Redis 配置内容总结

    命令 Redis 的配置文件位于 Redis 安装目录下,文件名为 redis.conf. 你可以通过 CONFIG 命令查看或设置配置项. (1)config get config_setting_ ...

  4. 循序渐进redis(一) —— redis的安装及可视化工具的使用

    1.安装 注意事项: 1.安装gcc 2.编译带参数: make MALLOC=libc 2.可视化客户端工具 推荐使用RedisClient,提供了基本的CRUD以及过期设置等操作的图形化接口,在项 ...

  5. Redis二进制安全概念

    二进制安全是指,在传输数据时,保证二进制数据的信息安全,也就是不被篡改.破译等,如果被攻击,能够及时检测出来. 二进制安全包含了密码学的一些东西,比如加解密.签名等. 举个例子,你把数据1111000 ...

  6. Redis二进制反转算法分析

    在 redis 源码中 dictScan 算法中用到了用到了非常经典的二进制反转算法,该算法对二进制的反转高效而实用,同时对于理解位运算也有非常大的帮助.先呈现源码: /* Function to r ...

  7. 99%的人都搞错了的java方法区存储内容,通过可视化工具HSDB和代码示例一次就弄明白了

    https://zhuanlan.zhihu.com/p/269134063  番茄番茄我是西瓜 那是我日夜思念深深爱着的人啊~ 已关注   6 人赞同了该文章 前言 本篇是java内存区域管理系列教 ...

  8. 通达OA 在工作流中直接查询表单内容的开发尝试(图文)

    一个朋友提出要在工作里直接查询表单内容的需求,原来他们把工作流当做业务系统来用.也算把工作流用到极致了.为了实现像软件里直接的查询功能,他想在办理工作流的时候直接能查询到表单里面的内容. 通过研究通达 ...

  9. 爬虫3 requests基础之下载图片用content(二进制内容)

    res = requests.get('http://soso3.gtimg.cn/sosopic/0/11129365531347748413/640') # print(res.content) ...

随机推荐

  1. mysql 安装报错集合

    mysql-5.6.39 源码编译安装报错 报错信息: /tmp/ccV858jD.s: Assembler messages: /tmp/ccV858jD.s: Fatal error: can't ...

  2. 使用生成对抗网络(GAN)生成手写字

    先放结果 这是通过GAN迭代训练30W次,耗时3小时生成的手写字图片效果,大部分的还是能看出来是数字的. 实现原理 简单说下原理,生成对抗网络需要训练两个任务,一个叫生成器,一个叫判别器,如字面意思, ...

  3. Ubuntu中git pull远程仓库时显示403错误

    # 报错内容 fatal: unable to access 'https://git.dev.tencent.com/chendongnan/sfedu_wx.git/': The requeste ...

  4. 小白学 Python 爬虫(15):urllib 基础使用(五)

    人生苦短,我用 Python 前文传送门: 小白学 Python 爬虫(1):开篇 小白学 Python 爬虫(2):前置准备(一)基本类库的安装 小白学 Python 爬虫(3):前置准备(二)Li ...

  5. 自学PHP的第22天---ThinkPHP中的路由、ThinkPHP目录结构

    这一切的一切都得从“Hello world”说起!!! 有很多东西在thinkPHP的官方开发文档上其实都有讲到,我在这里只是想记录自己每天坚持学习PHP的情况,今天接触ThinkPHP的路由,路由这 ...

  6. dotnet core gbk 编码错误解决方案

    .Net Core GBK解码 1.添加引用 System.Text.Encoding.CodePages 2.注册   Encoding.RegisterProvider(CodePagesEnco ...

  7. SpringBoot与JPA

    JPA是什么 JPA是Java Persistence API的简称,中文名Java持久层API,是JDK 5.0注解或XML描述对象-关系表的映射关系,并将运行期的实体对象持久化到数据库中. JPA ...

  8. 马拉车manacher

    目的:线性查找一个串的最长回文子串 时间复杂度:O(n) len[i]表示以i为中心的回文串的半径,mx即为当前计算回文串最右边字符的最大值,p是中心点mid,mx-i和2*p-1关于p对称 http ...

  9. ZOJ 3195 Design the city (LCA 模板题)

    Cerror is the mayor of city HangZhou. As you may know, the traffic system of this city is so terribl ...

  10. UESTC-1963咸鱼咕咕咕(二分图匹配)

    咸鱼咕咕咕 Time Limit: 1000 MS     Memory Limit: 64 MB Submit Status 咸鱼有个咕咕笼. 咕咕笼可以划分成m×nm×n个格子,每个小格子可以放下 ...