0 package main

1

2 import (

3 "log"

4 "strconv"

5 "errors"

6 "net/http"

7 "encoding/base64"

8 "encoding/binary"

9 "crypto/sha256"

10 "io/ioutil"

11 "time"

12 "runtime"

13 "os"

14 "fmt"

15 )

16

17 func resolve(url, id, answer string) ([]byte, error) {

18

19 req, err := http.NewRequest("GET", url, nil)

20 if err != nil {

21 return nil, err

22 }

23

24 req.AddCookie(&http.Cookie{Name: "pow-shield-id", Value: id})

25 req.AddCookie(&http.Cookie{Name: "pow-shield-answer", Value: answer})

26

27 client := &http.Client{}

28 resp, err := client.Do(req)

29 if err != nil {

30 return nil, err

31 }

32 defer resp.Body.Close()

33

34 if resp.StatusCode != 200 {

35 err = errors.New("status: " + strconv.Itoa(resp.StatusCode))

36 return nil, err

37 }

38

39 return ioutil.ReadAll(resp.Body)

40 }

41

42 func request(url string, work uint32, repeat int) {

43

44 rawData := make([]byte, 36)

45 resp, err := http.Get(url)

46 if err != nil {

47

48 log.Fatal(err)

49 }

50 defer resp.Body.Close()

51

52 cookies := resp.Cookies()

53 if (len(cookies) < 2) {

54 log.Fatalln("invalid response");

55 return

56 }

57 id := resp.Cookies()[0].Value

58 challenge := resp.Cookies()[1].Value

59 //ioutil.ReadAll(resp.Body)

60 resp.Body.Close()

61

62 data, err := base64.StdEncoding.DecodeString(challenge)

63 if err != nil {

64 log.Fatal("invalid base64:", err)

65 }

66 if len(data) != 32 {

67 log.Fatal("invalid data length", len(data))

68 }

69

70 copy(rawData, data)

71 var answer string

72 for i := uint32(0); i < 0xFFFFFFFF; i++ {

73 binary.LittleEndian.PutUint32(rawData[32:], i)

74 hash := sha256.Sum256(rawData[0:36])

75 start := binary.LittleEndian.Uint32(hash[0:4])

76 if start <= work {

77 answer = strconv.FormatUint(uint64(i), 10)

78 break;

79 }

80 i++

81 }

82

83 for i := 0; i < repeat; i++ {

84 data, err = resolve(url, id, answer)

85 if err != nil {

86 break

87 }

88 }

89 }

90

91 var count = 0

92

93 func requestRoutine(url string, work uint32, repeat int) {

94 for i := 0; ; i++ {

95 request(url, work, repeat)

96 count += repeat

97 }

98 }

99

100 func main() {

101 work := uint32(0x00005FFF)

102 repeat := 100

103 if len(os.Args) < 2 {

104 fmt.Println(os.Args[0] + " <url> [repeat] [work]")

105 return

106 }

107 if len(os.Args) > 2 {

108 i, err := strconv.Atoi(os.Args[2])

109 if err != nil {

110 fmt.Println("Invalid repeat value")

111 return

112 }

113 repeat = i

114 }

115 if len(os.Args) > 3 {

116 i, err := strconv.ParseUint(os.Args[3], 16, 32)

117 if err != nil {

118 fmt.Println("Invalid work value")

119 return

120 }

121 work = uint32(i)

122 }

123 start := time.Now().UnixMilli()

124 for i := 0; i < runtime.NumCPU(); i++ {

125 go requestRoutine(os.Args[1], work, repeat)

126 }

127 for {

128 time.Sleep(time.Second)

129 log.Println(int64(count) * 1000 /

130 (time.Now().UnixMilli() - start + 1),

131 "total request/second")

132 }

133 }

134