How is the Chrome Extension ID of an unpacked extension generated?
While I linked to this question that explains how to "pin" an ID for an unpacked extension, which would solve the practical problem OP faces, the question itself (as stated in the title) is interesting.
If we look at the Chromium source, we will see that the ID is simply a SHA hash of a (maybe-normalized, whatever that means) absolute path to the extension. Highlights from the code:
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// chromium/src/chrome/browser/extensions/unpacked_installer.cc
int UnpackedInstaller::GetFlags() {
std::string id = crx_file::id_util::GenerateIdForPath(extension_path_);
/* ... */
}
// chromium/src/components/crx_file/id_util.cc
std::string GenerateIdForPath(const base::FilePath& path) {
base::FilePath new_path = MaybeNormalizePath(path);
std::string path_bytes =
std::string(reinterpret_cast<const char*>(new_path.value().data()),
new_path.value().size() * sizeof(base::FilePath::CharType));
return GenerateId(path_bytes);
}
std::string GenerateId(const std::string& input) {
uint8 hash[kIdSize];
crypto::SHA256HashString(input, hash, sizeof(hash));
std::string output =
base::StringToLowerASCII(base::HexEncode(hash, sizeof(hash)));
ConvertHexadecimalToIDAlphabet(&output);
return output;
}
As such, it should ONLY depend on the absolute filesystem path to the extension folder.
Xan's answer is correct. However, just to extend it for the reference based on Chromium code above one could calculate extension id with this python code.
import hashlib
m = hashlib.sha256()
m.update(bytes(PATH.encode('utf-8')))
EXTID = ''.join([chr(int(i, base=16) + ord('a')) for i in m.hexdigest()][:32])