【问题标题】:Golang program to check a string list of patterns in another string list - password crackingGolang程序检查另一个字符串列表中的模式字符串列表 - 密码破解
【发布时间】:2021-09-14 15:56:00
【问题描述】:

社区,我需要改进以下代码的建议:

为了给出问题,程序执行以下操作:

  • 它将包含 sha2 哈希的文件读入字符串数组。
  • 它接受一个起始数字并连续计算哈希值。
  • 它使用文件(列表)中的哈希值检查计算的哈希值并打印匹配项。
//FILENAME: passcracker.go
package main

import (
    "fmt"
    "crypto/sha256"
    "os"
    "io/ioutil"
    "strings"
    "math/big"  
)

func isValueInList(value1 string, list []string) bool {
    for _, v := range list {
        if v == value1 {
            return true
        }
    }
    return false
}

func main() {
    if len(os.Args) <= 2 {
        fmt.Printf("USAGE : %s <PATTERNFILE> <STARTING_NUMBER>\n", os.Args[0])
        os.Exit(0)
    }

    fileName := os.Args[1]
    fileBytes, err := ioutil.ReadFile(fileName)

    if err != nil {
        fmt.Println(err)
        os.Exit(1)
    }
    
    strHashArr := strings.Split(string(fileBytes), "\r\n")

    startNum := new(big.Int)
    startNum.SetString(os.Args[2], 10)
    one := big.NewInt(1)

    //list := []string{ }
    var i int64
    for i = 0; i < 262144; i++ {
        h := sha256.New()
        h.Write([]byte(startNum.Bytes()))

        s := fmt.Sprintf("%x", h.Sum(nil))

        // Hash values are computed and added to a string list - A probable approach
        //list.append(s)

        if isValueInList(s, strHashArr) {
            fmt.Printf("Matched Hash %s for number %s\n",s,startNum)
        }
        startNum = startNum.Add(startNum,one)

    }
    // Probable approach to reduce the time
    // Computed hash string list is checked with the file hashes list
    // Function takes to string arrays 
    // Can it also use map or any other method for list in list comparison?
    //if isValueInList(list, strHashArr) {
        // get all the matched items and print the index value using the startNum value in a loop
    //}
}

密码哈希文件位于:https://pastebin.com/TWPxrb4R

要运行程序,请使用

passcracker hashes.txt 1000

程序打印匹配的哈希值以及识别的数字。

由于该程序仅计算有限的 262144 个哈希,因此打印速度更快。

现在为了改进程序以更快地输出匹配项,是否可以将哈希计算为字符串数组并调用函数来匹配文件中的哈希并在一次调用中返回匹配的索引?

由于该问题与密码破解方法非常相似,但这里的区别在于打印顺序计算和匹配的哈希值。它类似于一个连续的运行用户 ID。

由于输入的散列文件可能会变得非常大(大约几千个散列)并且连续的数字也可能很大,因此即使计算只是针对包含 32K 循环的散列文件,程序也会遇到困难10K 哈希。

目前为简洁起见,上述文件中的哈希数为 50,循环检查 256K 个数字,执行速度更快。

我们将不胜感激。谢谢。

【问题讨论】:

  • 您现在要做的最好的事情就是寻找更好的数据结构来存储和搜索文件中包含的哈希值。
  • 是的。我正在尝试一种不同的方法,一旦速度有所提高,我就会发布我的发现。还尝试了@steven-penny 提供的答案。欣赏cmets。谢谢!

标签: performance go string-matching password-hash


【解决方案1】:

我能够将速度提高三倍:

package main

import (
   "bufio"
   "crypto/sha256"
   "encoding/binary"
   "encoding/hex"
   "math/bits"
   "os"
   "testing"
)

func BenchmarkFast(b *testing.B) {
   f, err := os.Open("hashes.txt")
   if err != nil {
      b.Fatal(err)
   }
   defer f.Close()
   s := bufio.NewScanner(f)
   hash := make(map[[32]byte]struct{})
   for s.Scan() {
      var dst [32]byte
      hex.Decode(dst[:], s.Bytes())
      hash[dst] = struct{}{}
   }
   var num uint64
   for n := 0; n < b.N; n++ {
      buf := make([]byte, 8)
      binary.BigEndian.PutUint64(buf, num)
      buf = buf[bits.LeadingZeros64(num)>>3:]
      sum := sha256.Sum256(buf)
      if _, ok := hash[sum]; ok {
      }
      num++
   }
}

结果:

BenchmarkFast-12         5983708               198.2 ns/op
BenchmarkSlow-12         1946358               614.7 ns/op

【讨论】:

  • 非常感谢。这会将散列转换为十六进制,然后检查匹配项。我认为如果模式包含字符串,它不会转换为十六进制对吗?此外,对列表比较的任何想法都会有所帮助。我发布的程序是另一个程序的一部分,并且可能存在输入文件也可能包含模糊字符串哈希的情况。类似于 JWT 令牌,其中字符空间可能包含除十六进制数字之外的其他字符。
  • 您可以使用的另一个优化是每次都使用字节数组而不是计数器和编码。由于它是连续的,因此您可以碰撞最后一个字节,然后如果它被包裹,则碰撞前面的字节。
  • @StevenPenney 我不确定对于至少隐含地寻求帮助以加快代码速度的问题而言,哪些优化超出了范围,但在某些方面,这实际上类似于使用 OP 方法big.Int。原始代码都进行了手动携带增量和缓冲区编码;你摆脱了携带增量,而我建议摆脱编码。
  • @KyleLemons 我没有改变我的答案。如果您觉得如此倾向,请发布您自己的
猜你喜欢
  • 2018-06-06
  • 1970-01-01
  • 2016-06-16
  • 1970-01-01
  • 1970-01-01
  • 2012-11-23
  • 2017-04-27
  • 2019-07-27
  • 1970-01-01
相关资源
最近更新 更多