Header定义
// standard archive format - standard tar - ustar
struct TarHeader {
char name[100]; // 0 -99
char mode[8]; // 100-107
char uid[8]; // 108-115
char gid[8]; // 116-123
char size[12]; // 124-135
char mtime[12]; // 136-147
char chksum[8]; // 148-155
char typeflag; // 156
char linkname[100]; // 157-256
char magic[8]; // 257-264
char uname[32]; // 265-296
char gname[32]; // 297-328
char devmajor[8]; // 329-336
char devminor[8]; // 337-344
char prefix[155]; // 345-499
char padding[12]; // 500-511
};
- tar文件header固定长度为512byte
- 512byte全部由ASCILL码填充
- 未设置的字段填充0(ASCILL码中为空字符)
- 字段分为字符串和数值
- 字符串
- 以name为例,字符串按每个字符,转换为ASCILL码后填充
- 从0开始填充,假设写入name为bin
- 在数组中显示为[98 105 110 0 ... 0]
- 数值
- 以size为例,以八进制处理数值124-134填充ASCILL码
- 135保留ASCILL码空字符
- 124-134每一位都要写入,为0的写入48(ASCILL码中的0)
- 假设写入size为114514
- 在数组中显示为[48 48 48 48 48 51 51 55 53 50 50 0]
- 字符串显示为00000337522�
- 特殊字段magic
- 固定值,为ustar(null)00
- 在数组中显示为[117 115 116 97 114 0 48 48]
Header构造的golang实现
package util
import (
"fmt"
"time"
"unicode/utf8"
)
type TarHeaderCreater struct {
// | name | 100 | 0 -99 |
// | mode | 8 | 100-107 |
// | uid | 8 | 108-115 |
// | gid | 8 | 116-123 |
// | size | 12 | 124-135 |
// | mtime | 12 | 136-147 |
// | chksum | 8 | 148-155 |
// | typeflag | 1 | 156
// | linkname | 100 | 157-256 |
// | magic | 8 | 257-264 |
// | uname | 32 | 265-296 |
// | gname | 32 | 297-328 |
// | devmajor | 8 | 329-336 |
// | devminor | 8 | 337-344 |
// | prefix | 155 | 345-499 |
// | padding | 12 | 500-511 |
buf [512]byte
}
func (hc *TarHeaderCreater) Init() {
// Init all 0
for i := 0; i < 512; i++ {
hc.buf[i] = 0
}
// magic
hc.writeChar(257, "ustar")
hc.writeInt(263, 264, 0)
// devmajor
hc.writeInt(329, 335, 0)
// devminor
hc.writeInt(337, 343, 0)
}
func (hc *TarHeaderCreater) writeChar(start int, str string) error {
for i, c := range str {
if c < utf8.RuneSelf {
hc.buf[start+i] = byte(int(c))
} else {
return fmt.Errorf("fail to change char: %c to ASCII", c)
}
}
return nil
}
func (hc *TarHeaderCreater) writeInt(start, end, val int64) {
for i := end; i >= start; i-- {
if val <= 0 {
hc.buf[i] = byte(48)
} else {
tmp := val % 8
val /= 8
hc.buf[i] = byte(tmp + 48)
}
}
}
func (hc *TarHeaderCreater) SetName(name string) error {
return hc.writeChar(0, name)
}
func (hc *TarHeaderCreater) SetMode(mode int64) {
hc.writeInt(100, 106, mode)
}
func (hc *TarHeaderCreater) SetUid(uid int64) {
hc.writeInt(108, 114, uid)
}
func (hc *TarHeaderCreater) SetGid(gid int64) {
hc.writeInt(116, 122, gid)
}
func (hc *TarHeaderCreater) SetTypeFlag(b byte) {
hc.buf[156] = b
}
func (hc *TarHeaderCreater) SetLinkName(linkName string) error {
return hc.writeChar(157, linkName)
}
func (hc *TarHeaderCreater) SetModTime(modeTime string) error {
t, err := time.Parse("2006-01-02T15:04:05Z07:00", modeTime)
if err != nil {
return err
}
hc.writeInt(136, 146, t.Unix())
return nil
}
func (hc *TarHeaderCreater) SetSize(size int64) {
hc.writeInt(124, 134, size)
}
func (hc *TarHeaderCreater) SetChksum() {
chksum := int64(256)
for _, b := range hc.buf {
chksum += int64(b)
}
hc.writeInt(148, 153, chksum)
hc.buf[155] = 32
}
标签:12,tar,48,char,header,格式,hc,100,ASCILL
From: https://www.cnblogs.com/umichan0621/p/18186171