mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-11-03 21:16:26 +01:00 
			
		
		
		
	* Initial commit for 2FA support Signed-off-by: Andrew <write@imaginarycode.com> * Add vendored files * Add missing depends * A few clean ups * Added improvements, proper encryption * Better encryption key * Simplify "key" generation * Make 2FA enrollment page more robust * Fix typo * Rename twofa/2FA to TwoFactor * UNIQUE INDEX -> UNIQUE
		
			
				
	
	
		
			120 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			120 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
package utils
 | 
						|
 | 
						|
// BitList is a list that contains bits
 | 
						|
type BitList struct {
 | 
						|
	count int
 | 
						|
	data  []int32
 | 
						|
}
 | 
						|
 | 
						|
// NewBitList returns a new BitList with the given length
 | 
						|
// all bits are initialize with false
 | 
						|
func NewBitList(capacity int) *BitList {
 | 
						|
	bl := new(BitList)
 | 
						|
	bl.count = capacity
 | 
						|
	x := 0
 | 
						|
	if capacity%32 != 0 {
 | 
						|
		x = 1
 | 
						|
	}
 | 
						|
	bl.data = make([]int32, capacity/32+x)
 | 
						|
	return bl
 | 
						|
}
 | 
						|
 | 
						|
// Len returns the number of contained bits
 | 
						|
func (bl *BitList) Len() int {
 | 
						|
	return bl.count
 | 
						|
}
 | 
						|
 | 
						|
func (bl *BitList) grow() {
 | 
						|
	growBy := len(bl.data)
 | 
						|
	if growBy < 128 {
 | 
						|
		growBy = 128
 | 
						|
	} else if growBy >= 1024 {
 | 
						|
		growBy = 1024
 | 
						|
	}
 | 
						|
 | 
						|
	nd := make([]int32, len(bl.data)+growBy)
 | 
						|
	copy(nd, bl.data)
 | 
						|
	bl.data = nd
 | 
						|
}
 | 
						|
 | 
						|
// AddBit appends the given bits to the end of the list
 | 
						|
func (bl *BitList) AddBit(bits ...bool) {
 | 
						|
	for _, bit := range bits {
 | 
						|
		itmIndex := bl.count / 32
 | 
						|
		for itmIndex >= len(bl.data) {
 | 
						|
			bl.grow()
 | 
						|
		}
 | 
						|
		bl.SetBit(bl.count, bit)
 | 
						|
		bl.count++
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
// SetBit sets the bit at the given index to the given value
 | 
						|
func (bl *BitList) SetBit(index int, value bool) {
 | 
						|
	itmIndex := index / 32
 | 
						|
	itmBitShift := 31 - (index % 32)
 | 
						|
	if value {
 | 
						|
		bl.data[itmIndex] = bl.data[itmIndex] | 1<<uint(itmBitShift)
 | 
						|
	} else {
 | 
						|
		bl.data[itmIndex] = bl.data[itmIndex] & ^(1 << uint(itmBitShift))
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
// GetBit returns the bit at the given index
 | 
						|
func (bl *BitList) GetBit(index int) bool {
 | 
						|
	itmIndex := index / 32
 | 
						|
	itmBitShift := 31 - (index % 32)
 | 
						|
	return ((bl.data[itmIndex] >> uint(itmBitShift)) & 1) == 1
 | 
						|
}
 | 
						|
 | 
						|
// AddByte appends all 8 bits of the given byte to the end of the list
 | 
						|
func (bl *BitList) AddByte(b byte) {
 | 
						|
	for i := 7; i >= 0; i-- {
 | 
						|
		bl.AddBit(((b >> uint(i)) & 1) == 1)
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
// AddBits appends the last (LSB) 'count' bits of 'b' the the end of the list
 | 
						|
func (bl *BitList) AddBits(b int, count byte) {
 | 
						|
	for i := int(count) - 1; i >= 0; i-- {
 | 
						|
		bl.AddBit(((b >> uint(i)) & 1) == 1)
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
// GetBytes returns all bits of the BitList as a []byte
 | 
						|
func (bl *BitList) GetBytes() []byte {
 | 
						|
	len := bl.count >> 3
 | 
						|
	if (bl.count % 8) != 0 {
 | 
						|
		len++
 | 
						|
	}
 | 
						|
	result := make([]byte, len)
 | 
						|
	for i := 0; i < len; i++ {
 | 
						|
		shift := (3 - (i % 4)) * 8
 | 
						|
		result[i] = (byte)((bl.data[i/4] >> uint(shift)) & 0xFF)
 | 
						|
	}
 | 
						|
	return result
 | 
						|
}
 | 
						|
 | 
						|
// IterateBytes iterates through all bytes contained in the BitList
 | 
						|
func (bl *BitList) IterateBytes() <-chan byte {
 | 
						|
	res := make(chan byte)
 | 
						|
 | 
						|
	go func() {
 | 
						|
		c := bl.count
 | 
						|
		shift := 24
 | 
						|
		i := 0
 | 
						|
		for c > 0 {
 | 
						|
			res <- byte((bl.data[i] >> uint(shift)) & 0xFF)
 | 
						|
			shift -= 8
 | 
						|
			if shift < 0 {
 | 
						|
				shift = 24
 | 
						|
				i++
 | 
						|
			}
 | 
						|
			c -= 8
 | 
						|
		}
 | 
						|
		close(res)
 | 
						|
	}()
 | 
						|
 | 
						|
	return res
 | 
						|
}
 |