>

go语言落成将重大数据写入图片中,gomemcache包源

- 编辑:金沙国际平台登录 -

go语言落成将重大数据写入图片中,gomemcache包源

因为beego中的cache模块中的子模块memcached引用了这个包,所以也对这包的源码进行分析了下。花了一定的时间编写整理这篇博客,这个包一共两个文件,源码文件。关于memcache学习,可以到

原理:将数据的二进制形式写入图像红色通道数据二进制的低位
只支持png格式的输出
写入数据
go run shadow.go -in="c.jpg" -data="hide me" -out="out.png"
读取数据
go run shadow.go -in="out.png"

1)func New(server ...string) *Client用法:mc := memcache.New("127.0.0.1:11211")

复制代码 代码如下:

主要可以分为以下步骤:1、传入一个合法的memcached服务器地址信息2、定义变量和赋值

package main
import (
    "errors"
    "flag"
    "fmt"
    "image"
    "image/color"
    _ "image/jpeg"
    "image/png"
    "log"
    "math"
    "os"
)
var FLAG = [4]byte{0x13, 0x14, 0x52, 0x00} //shadow flag.
//byte to 8 bits
func Byte2bits(b byte) (a [8]byte) {
    var c uint8 = 7
    var i uint8
    for i = 0; i < 8; i++ {
        a[i] = b >> (c - i) & 1
    }
    return
}
//8 bits to byte.
func Bits2Byte(a [8]byte) (b byte) {
    for i := 0; i < 8; i++ {
        b += a[i] * uint8(math.Pow(2, float64(7-i)))
    }
    return
}
//uint32 to 4 bytes.
func Uint32ToBytes(i uint32) (b [4]byte) {
    b[0] = uint8(i >> 24)
    b[1] = uint8(i >> 16 & 0xffff)
    b[2] = uint8(i >> 8 & 0xff)
    b[3] = uint8(i & 0xff)
    return
}
//4 bytes to uint32.
func Bytes2Uint32(b [4]byte) (i uint32) {
    var j uint32
    for ; j < 4; j++ {
        i += uint32(b[j]) << (24 - j*8)
    }
    return
}
func BuildShadowHeader(length uint32) (b [8]byte) {
    var i int
    for ; i < 4; i++ {
        b[i] = FLAG[i]
    }
    a := Uint32ToBytes(length)
    for ; i < 8; i++ {
        b[i] = a[i-4]
    }
    return
}
func WriteShadow(b []byte, im image.Image) (out image.Image, err error) {
    max := im.Bounds().Max.X*im.Bounds().Max.Y/8 - 64
    b_len := len(b)
    if len(b) > max {
        return nil, errors.New("image does not have enough space for shadow.")
    }
    head := BuildShadowHeader(uint32(b_len))
    var bb byte
    var bs [8]byte
    var i int
    out, err = SetImage(im, func(index, x, y int, in, out image.Image) {
        rgba := readRGBAColor(im.At(x, y))
        if index < b_len*8+64 {
            if index < 64 {
                bb = head[index/8]
            } else {
                bb = b[index/8-8]
            }
            bs = Byte2bits(bb)
            i = index % 8
            if bs[i] != rgba.R&1 {
                if bs[i] == 0 {
                    rgba.R -= 1
                } else {
                    rgba.R += 1
                }
            }
        }
        if v := out.(*image.RGBA); v != nil {
            v.SetRGBA(x, y, rgba)
        }
    })
    if err != nil {
        return nil, err
    }
    return
}
func ReadShadowData(im image.Image) (b []byte, err error) {
    head, err := ReadShadowHeader(im)
    if err != nil {
        return nil, err
    }
    length := int(ReadShadowLength(head))
    var bk []byte = make([]byte, length*8)
    b = make([]byte, length)
    _, err = SetImage(im, func(index, x, y int, in, out image.Image) {
        if index >= 64 && index < length*8+64 {
            R := readRGBAColor(im.At(x, y)).R
            bk[index-64] = uint8(R & 1)
        }
    })
    var bb [8]byte
    var bs []byte
    for i := 0; i < length; i++ {
        bs = bk[8*i : 8*(i+1)]
        for j := 0; j < 8; j++ {
            bb[j] = bs[j]
        }
        b[i] = Bits2Byte(bb)
    }
    return
}
func ReadShadowHeader(im image.Image) (b [8]byte, err error) {
    var bm [64]byte
    _, err = SetImage(im, func(index, x, y int, in, out image.Image) {
        rgba := readRGBAColor(im.At(x, y))
        if index < 64 {
            bm[index] = uint8(rgba.R & 1)
        }
    })
    if err != nil {
        return
    }
    var bb [8]byte
    var bs []byte
    for i := 0; i < 8; i++ {
        bs = bm[8*i : 8*(i+1)]
        for j := 0; j < 8; j++ {
            bb[j] = bs[j]
        }
        b[i] = Bits2Byte(bb)
    }
    return
}
func ReadShadowFlag(b [8]byte) (a [4]byte) {
    for i := 0; i < 4; i++ {
        a[i] = b[i]
    }
    return
}
func ReadShadowLength(b [8]byte) uint32 {
    var bb [4]byte
    for i := 4; i < 8; i++ {
        bb[i-4] = b[i]
    }
    return Bytes2Uint32(bb)
}
func OpenImage(path string) (image.Image, error) {
    im_read, err := os.Open(path)
    defer im_read.Close()
    if err != nil {
        return nil, err
    }
    im, _, err := image.Decode(im_read)
    if err != nil {
        return nil, err
    }
    return im, nil
}
//modify image
func SetImage(im image.Image, f func(index, x, y int, in, out image.Image)) (out image.Image, err error) {
    if f == nil {
        return im, nil
    }
    index := 0
    bounds := im.Bounds()
    out = image.NewRGBA(bounds)
    var m *image.RGBA = out.(*image.RGBA)
    for y := bounds.Min.Y; y < bounds.Max.Y; y++ {
        for x := bounds.Min.X; x < bounds.Max.X; x++ {
            m.Set(x, y, im.At(x, y))
            f(index, x, y, im, out)
            index += 1
        }
    }
    return out, nil
}
//conert any color to RABGA color.
func readRGBAColor(from_color color.Color) color.RGBA {
    return color.RGBAModel.Convert(from_color).(color.RGBA)
}
//only write to jpeg formats.
func WriteImage(path string, im image.Image) error {
    out, err := os.OpenFile(path, os.O_CREATE, os.ModePerm)
    defer out.Close()
    if err != nil {
        return err
    }
    err = png.Encode(out, im)
    if err != nil {
        return err
    }
    return nil
}
var read_in string
var write_out string
var data string
func init() {
    flag.StringVar(&read_in, "in", "", "image path read in.")
    flag.StringVar(&write_out, "out", "out.jpg", "image path write out.")
    flag.StringVar(&data, "data", "", "data to shadow.")
}
func errHandle(err error) {
    if err != nil {
        log.Fatal(err)
    }
}
func main() {
    flag.Parse()
    if read_in == "" {
        fmt.Println("Options:")
        flag.PrintDefaults()
        return
    }
    im, err := OpenImage(read_in)
    errHandle(err)
    if data != "" {
        out, err := WriteShadow([]byte(data), im)
        errHandle(err)
        err = WriteImage(write_out, out)
        errHandle(err)
    } else {
        head, err := ReadShadowHeader(im)
        errHandle(err)
        _flag := ReadShadowFlag(head)
        if _flag != FLAG {
            fmt.Println("image doesn't have shadow data.")
            return
        }
        data, err := ReadShadowData(im)
        errHandle(err)
        fmt.Println("shadow:", string(data))
    }
}

New方法流程图如下,点击下载

以上所述就是本文的全部内容了,希望大家能够喜欢。

图片 1image.png

您可能感兴趣的文章:

  • Django Admin实现上传图片校验功能
  • Django实现图片文字同时提交的方法
  • Django中实现点击图片链接强制直接下载的方法
  • go语言读取json并下载高清妹子图片
  • go语言实现抓取高清图片
  • GO语言实现批量压缩图片和水印
  • Go语言图片处理和生成缩略图的方法
  • golang实现通过smtp发送电子邮件的方法
  • golang基于websocket实现的简易聊天室程序
  • golang使用sort接口实现排序示例
  • golang守护进程用法示例
  • golang实现http服务器处理静态文件示例
  • golang image图片处理示例

2)func (c *Client) Add(item *Item) error作用:mc := memcache.New("127.0.0.1:11211")mc.Add(&memcache.Item{Key:"data",Value:[]byte

主要可以分为以下步骤:1、选择一个memcache服务器并获取连接2、发送数据到memcached服务器3、接收memcached信息和处理连接Add方法流程图如下,点击下载

图片 2image.png

3)func (c *Client) Set(item *Item) error用法:mc := memcache.New("127.0.0.1:11211")mc.Set(&memcache.Item{Key:"data",Value:[]byte

主要分为以下步骤:1、选择一个memcached服务器并进行连接2、向连接的那个memcached服务器发送数据并处理相关内容3、连接处理Set方法流程图如下,点击下载

图片 3image.png

4)func (c *Client) Get(key string) (item *Item, err error)用法:mc := memcache.New("127.0.0.1:11211")i, err := mc.Getfmt.Println

主要可分为三个步骤1:获取tcp连接2:发送数据到memcached3:处理memcached返回消息和tcp连接处理Get方法流程图如下,点击下载

图片 4image.png

5)func (c Client) GetMulti(keys []string) (map[string]Item, error)用法:mc := memcache.New("127.0.0.1:11211")items, err := mc.GetMulti([]string{"data1","data2","data3"})

主要可分为三个步骤1:获取tcp连接2:发送数据到memcached3:处理memcached返回消息和tcp连接处理GetMulti方法流程图如下,点击下载

图片 5image.png

6)func (c *Client) Increment(key string, delta uint64) (newValue uint64, err error)用法:mc := memcache.New("127.0.0.1:11211")newVal, err := mc.Increment("test", 2)fmt.Println(newVal, err)

作用:将原来键的值加上指定数,可分为以下两种情况:1、如果原来的是一个数字,则加上指定数,返回修改后的值和nil2、如果原来的不是一个数,则返回0和报错信息

内部执行步骤:1、连接memcached服务器2、发送数据到memcached服务器3、断开连接,对连接进行回收或释放Delete方法流程图如下,点击下载

图片 6image.png

7)func (c *Client) Decrement(key string, delta uint64) (newValue uint64, err error)用法:mc := memcache.New("127.0.0.1:11211")newVal, err := mc.Decrement("test", 2)fmt.Println(newVal, err)

作用:将原来键的值减去指定数,可分为以下两种情况:1、如果原来的是一个数字,则减去指定数,返回修改后的值和nil2、如果原来的不是一个数,则返回0和报错信息Decrement方法流程图如下,点击下载

图片 7image.png

8)func (c *Client) CompareAndSwap(item *Item) error用法:mc := memcache.New("127.0.0.1:11211")mc.CompareAndSwap(&memcache.Item{Key:"data",Value:[]byte

封装发给memcached服务器的命令是:cas data 0 0 9 0主要分为以下步骤:1、选择一个memcached服务器地址并进行连接2、向memcached服务器发送数据和处理服务器返回的信息3、连接结束处理CompareAndSwap方法流程图如下,[点击下载]()

图片 8image.png

9)func (c *Client) FlushAll() error用法:mc := memcache.New("127.0.0.1:11211")err := mc.FlushAll()

用于清理缓存中的所有 key=>value 对

主要可以分为以下步骤:1、往每个memcached服务器发送数据和接收处理memcached信息2、和处理连接FlushAll方法流程图如下,点击下载

图片 9image.png

10)func (c *Client) Replace() error用法:mc := memcache.New("127.0.0.1:11211")err := mc.Replace()发送replace命令到mecmached服务器,该命令用于替换已存在的key的value。如果 key 不存在,则替换失败,并且您将获得响应 NOT_STORED。

主要可以分为以下步骤:1、往每个memcached服务器发送数据和接收处理memcached信息2、和处理连接Replace方法流程图如下,点击下载

图片 10image.png

11)func (c *Client) Touch(key string, seconds int32) (err error)用法:mc := memcache.New("127.0.0.1:11211")err := mc.Touch("data", 120)发送touch命令到mecmached服务器,如果key不存在,则会返回错误,如果key存在,则会在设置的时间后自动删除。

主要可以分为以下步骤:1、获取服务器地址操作2、往每个memcached服务器发送数据和接收处理memcached信息3、连接处理Touch方法流程图如下,点击下载

图片 11image.png

12)func (c *Client) Delete(key string) error用法:mc := memcache.New("127.0.0.1:11211")err := mc.Delete

将原有key对应的内容删除

主要可以分为以下步骤:1、获取连接2、发送数据到memcached服务器3、接收memcached信息和处理连接Delete方法流程图如下,点击下载

图片 12image.png

13)func (c *Client) DeleteAll() error

用法:mc := memcache.New("127.0.0.1:11211")err := mc.DeleteAll()将内容删除(和Delete共用一套实现代码)

主要可以分为以下步骤:1、获取连接2、发送数据到memcached服务器3、接收memcached信息和处理连接DeleteAll方法流程图如下,点击下载

图片 13image.png

相关链接:源码链接:

本文由编程发布,转载请注明来源:go语言落成将重大数据写入图片中,gomemcache包源