AlistGo/alist · error

无法匹配acw_sc__v2

Error message

无法匹配acw_sc__v2

What it means

CalcAcwScV2 fails when the anti-bot challenge page returned by LanZou (via an Alibaba-style WAF) does not contain the expected arg1='<HEX>' payload matched by the regex `arg1='([0-9A-Z]+)'`. The driver then cannot compute the acw_sc__v2 cookie needed to fetch the real page.

Source

Thrown at drivers/lanzou/help.go:128

		}
		if inComment || inSingleLineComment {
			continue
		}
		result.WriteByte(v)
	}

	return result.String()
}

var findAcwScV2Reg = regexp.MustCompile(`arg1='([0-9A-Z]+)'`)

// 在页面被过多访问或其他情况下,有时候会先返回一个加密的页面,其执行计算出一个acw_sc__v2后放入页面后再重新访问页面才能获得正常页面
// 若该页面进行了js加密,则进行解密,计算acw_sc__v2,并加入cookie
func CalcAcwScV2(html string) (string, error) {
	log.Debugln("acw_sc__v2", html)
	acwScV2s := findAcwScV2Reg.FindStringSubmatch(html)
	if len(acwScV2s) != 2 {
		return "", fmt.Errorf("无法匹配acw_sc__v2")
	}
	return HexXor(Unbox(acwScV2s[1]), "3000176000856006061501533003690027800375"), nil
}

func Unbox(hex string) string {
	var box = []int{6, 28, 34, 31, 33, 18, 30, 23, 9, 8, 19, 38, 17, 24, 0, 5, 32, 21, 10, 22, 25, 14, 15, 3, 16, 27, 13, 35, 2, 29, 11, 26, 4, 36, 1, 39, 37, 7, 20, 12}
	var newBox = make([]byte, len(hex))
	for i := 0; i < len(box); i++ {
		j := box[i]
		if len(newBox) > j {
			newBox[j] = hex[i]
		}
	}
	return string(newBox)
}

func HexXor(hex1, hex2 string) string {
	var out strings.Builder

View on GitHub (pinned to 843d9dc814)

Solutions

  1. Enable debug logs and inspect the logged challenge HTML (log.Debugln prints it) to see the new format
  2. Reduce request frequency / wait: some challenge pages are rate-limit responses that clear after a pause
  3. Update OpenList to a newer version where the lanzou helper regex/algorithm matches the current challenge
  4. As a driver maintainer: extend findAcwScV2Reg to also match the new arg1 format (e.g. allow lowercase hex) and re-derive the XOR key

Example fix

// before
var findAcwScV2Reg = regexp.MustCompile(`arg1='([0-9A-Z]+)'`)
// after (also accept lowercase and larger alphabets used by newer challenge pages)
var findAcwScV2Reg = regexp.MustCompile(`arg1='([0-9A-Za-z]+)'`)
Defensive patterns

Strategy: retry

Type guard

func isAcwScV2Challenge(html string) bool {
    return findAcwScV2Reg.MatchString(html)
}

Try / catch

v, err := CalcAcwScV2(html)
if err != nil {
    if !isAcwScV2Challenge(html) {
        // not a challenge page at all — do not retry the same way
        return fmt.Errorf("unexpected page instead of challenge: %w", err)
    }
    // challenge present but unparseable: back off and retry once later
    time.Sleep(30 * time.Second)
}

Prevention

When it happens

Trigger: A LanZou request receives a JS challenge page whose format changed (different obfuscation, different variable name, or an HTML-escaped payload), so FindStringSubmatch returns no groups and len(acwScV2s) != 2.

Common situations: LanZou/WAF frontend updated its anti-crawler script; rate-limiting returning a different block page (e.g. plain 403 HTML); regional CDN nodes serving a newer challenge variant; the constant XOR key '3000176000856006061501533003690027800375' no longer matching the deployed script.

Related errors


AI-assisted analysis of AlistGo/alist@843d9dc814 (2026-08-15). Data as JSON: /api/errors/c8b8609efbb7121c. Report an issue: GitHub.