# -*- coding: ascii -*- # ASCII-safe writer: builds Chinese via unicode escapes, writes UTF-8 no BOM. from __future__ import print_function import os import sys ROOT = os.path.dirname(os.path.abspath(__file__)) TARGET = os.path.join( ROOT, "fs-store", "src", "main", "java", "com", "fs", "store", "utils", "CompatiblePasswordEncoder.java", ) # Chinese via unicode escapes (real chars after decode, not literal \\u in output) L10 = " * " + "\u5bc6\u7801\u7f16\u7801\u5668\uff1a\u65b0\u5bc6\u7801\u4f7f\u7528 BCrypt\uff1b\u5b58\u91cf MD5 \u5bc6\u7801\u517c\u5bb9\u6821\u9a8c\u3002" L12 = " * matches \u5185\u5bf9 MD5 \u6210\u529f\u4ec5\u8fd4\u56de true\uff0c\u4e0d\u5199\u5e93\uff08\u65e0\u7528\u6237\u4e0a\u4e0b\u6587\u65f6\u65e0\u6cd5\u5b89\u5168\u5347\u7ea7\uff09\u3002" L13 = " * \u767b\u5f55\u6210\u529f\u540e\u7531 LoginService / LoginServiceScrm \u68c0\u6d4b isLegacyMd5 \u5e76\u5347\u7ea7\u4e3a BCrypt\u3002" C_BCRYPT = " // BCrypt \u5bc6\u6587" C_MD5 = " // \u5b58\u91cf MD5 hex \u517c\u5bb9\uff08\u7b97\u6cd5\u4e0e MD5PasswordEncoder \u4e00\u81f4\uff09" J_LEGACY = " * \u5224\u65ad\u662f\u5426\u4e3a\u5386\u53f2 MD5 \u5bc6\u6587\uff08\u975e BCrypt\uff09" J_BCRYPT = " * \u5224\u65ad\u662f\u5426\u4e3a BCrypt \u5bc6\u6587\uff08$2a$ / $2b$ / $2y$\uff09" J_MD5ALG = " * \u4e0e\u73b0\u6709 MD5PasswordEncoder \u76f8\u540c\u7684 MD5 hex \u7b97\u6cd5" content = "\n".join([ "package com.fs.store.utils;", "", "import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;", "import org.springframework.security.crypto.password.PasswordEncoder;", "", "import java.security.MessageDigest;", "import java.security.NoSuchAlgorithmException;", "", "/**", L10, " *

", L12, L13, " */", "public class CompatiblePasswordEncoder implements PasswordEncoder {", "", " private final BCryptPasswordEncoder bcryptPasswordEncoder = new BCryptPasswordEncoder();", "", " @Override", " public String encode(CharSequence rawPassword) {", " return bcryptPasswordEncoder.encode(rawPassword);", " }", "", " @Override", " public boolean matches(CharSequence rawPassword, String encodedPassword) {", " if (encodedPassword == null || rawPassword == null) {", " return false;", " }", C_BCRYPT, " if (isBcrypt(encodedPassword)) {", " return bcryptPasswordEncoder.matches(rawPassword, encodedPassword);", " }", C_MD5, " return md5Hex(rawPassword.toString()).equalsIgnoreCase(encodedPassword);", " }", "", " /**", J_LEGACY, " */", " public static boolean isLegacyMd5(String encodedPassword) {", " return encodedPassword != null && !isBcrypt(encodedPassword);", " }", "", " /**", J_BCRYPT, " */", " public static boolean isBcrypt(String encodedPassword) {", " return encodedPassword != null", " && (encodedPassword.startsWith(\"$2a$\")", " || encodedPassword.startsWith(\"$2b$\")", " || encodedPassword.startsWith(\"$2y$\"));", " }", "", " /**", J_MD5ALG, " */", " private static String md5Hex(String rawPassword) {", " try {", " MessageDigest md = MessageDigest.getInstance(\"MD5\");", " byte[] digest = md.digest(rawPassword.getBytes());", " StringBuilder sb = new StringBuilder();", " for (byte b : digest) {", " sb.append(String.format(\"%02x\", b));", " }", " return sb.toString();", " } catch (NoSuchAlgorithmException e) {", " throw new RuntimeException(\"MD5 algorithm not found\", e);", " }", " }", "}", "", ]) # UTF-8 without BOM with open(TARGET, "wb") as f: f.write(content.encode("utf-8")) lines = content.split("\n") line10 = lines[9] print("LINE10=" + line10) print("HAS_CN=" + str("\u5bc6\u7801\u7f16\u7801\u5668" in line10)) raw = open(TARGET, "rb").read(3) print("BOM=" + str(raw == b"\xef\xbb\xbf")) print("WROTE=" + TARGET)